見出し画像

データベースから複数件取得するのにORDER BYしない人へ

絶対にして。

わかる。指定しなくてもなんとなくID順に取得されるような動きをする。
しかしながらレコードを複数件取得する場合はORDER BYを絶対に指定して。

(わかると思うが、取得したレコードに対して並び順が重要で無い場合はこの限りでは無い)

指定しなくても大丈夫と思われる方もそうでない方も、以下MySQLの例題をいくつか紹介していくので是非目を通してほしい。

あなたは全ての例題に正解を出せるだろうか。

まずは下準備。


MySQLのバージョンは8.0.28を使用する。

mysql> SELECT VERSION();
+-----------+
| VERSION() |
+-----------+
| 8.0.28    |
+-----------+
1 row in set (0.00 sec)

`id`, `age`, `name`の列を持ち、
`id`がプライマリキーで、
`age`列からインデックスが作成される、
`users`テーブルを作成する。

CREATE TABLE
  `users` (
    `id` int,
    `age` int,
    `name` VARCHAR(255),
    PRIMARY KEY (`id`),
    KEY `age` (`age`)
  )
;

適当なデータを10件挿入する。(ChatGPT便利)

INSERT INTO
  `users`
  (`id`, `age`, `name`)
VALUES
  (1, 25, 'Alice'),
  (2, 30, 'Bob'),
  (3, 22, 'Charlie'),
  (4, 28, 'Diana'),
  (5, 35, 'Evan'),
  (6, 27, 'Fay'),
  (7, 24, 'George'),
  (8, 33, 'Hannah'),
  (9, 29, 'Ian'),
  (10, 26, 'Judy')
;


例題1

さて、このテーブルに以下のシンプルなSELECT文を投げる。

SELECT
  id,
  age,
  name
FROM
  users
;

結果はどうなるだろうか。少し考えてみてほしい。






結果は以下のようになる。



+----+------+---------+
| id | age  | name    |
+----+------+---------+
|  1 |   25 | Alice   |
|  2 |   30 | Bob     |
|  3 |   22 | Charlie |
|  4 |   28 | Diana   |
|  5 |   35 | Evan    |
|  6 |   27 | Fay     |
|  7 |   24 | George  |
|  8 |   33 | Hannah  |
|  9 |   29 | Ian     |
| 10 |   26 | Judy    |
+----+------+---------+
10 rows in set (0.00 sec)

ORDER BYを指定せずとも`id`の昇順になっており、いい感じに見える。


例題2

次はWHERE句で`age`列に対して条件を指定した場合。

SELECT
  id,
  age,
  name
FROM
  users
WHERE
  (age > 10)
;

どうなるだろうか。また少し考えてみてほしい。





結果は以下のようになる。



+----+------+---------+
| id | age  | name    |
+----+------+---------+
|  1 |   25 | Alice   |
|  2 |   30 | Bob     |
|  3 |   22 | Charlie |
|  4 |   28 | Diana   |
|  5 |   35 | Evan    |
|  6 |   27 | Fay     |
|  7 |   24 | George  |
|  8 |   33 | Hannah  |
|  9 |   29 | Ian     |
| 10 |   26 | Judy    |
+----+------+---------+
10 rows in set (0.00 sec)

想像通りだっただろうか。またいい感じに`id`の昇順となった。


例題3

では以下の例ではどうだろうか。
WHERE句の条件を少し変更した。

SELECT
  id,
  age,
  name
FROM
  users
WHERE
  (age > 25)
;

WHERE句の条件により、取得されるレコード数は7件となる。
並び順はどうなるだろうか。また少し考えてみてほしい。






結果は以下のようになる。



+----+------+--------+
| id | age  | name   |
+----+------+--------+
| 10 |   26 | Judy   |
|  6 |   27 | Fay    |
|  4 |   28 | Diana  |
|  9 |   29 | Ian    |
|  2 |   30 | Bob    |
|  8 |   33 | Hannah |
|  5 |   35 | Evan   |
+----+------+--------+
7 rows in set (0.00 sec)

取得結果は`id`ではなく、`age`の昇順になっている。
ORDER BYに`age`列を指定するなどはしていないにも関わらず。


例題4

もう1題。
テーブルへ1レコード追加する。

INSERT INTO
  `users`
  (`id`, `age`, `name`)
VALUES
  (11, 9, 'Michael')
;

この状態で、先ほど実行して`id`の昇順が返ってきたSELECT文をもう一度投げてみるとどうなるだろうか。

SELECT
  id,
  age,
  name
FROM
  users
WHERE
  (age > 10)
;

賢い方であれば想像がつくと思う。考えてみてほしい。





宣伝(他にこんな記事を書いています)





結果は以下のようになる。



+----+------+---------+
| id | age  | name    |
+----+------+---------+
|  1 |   25 | Alice   |
|  2 |   30 | Bob     |
|  3 |   22 | Charlie |
|  4 |   28 | Diana   |
|  5 |   35 | Evan    |
|  6 |   27 | Fay     |
|  7 |   24 | George  |
|  8 |   33 | Hannah  |
|  9 |   29 | Ian     |
| 10 |   26 | Judy    |
+----+------+---------+
10 rows in set (0.00 sec)

`id`の昇順である。

え、なんで?
コピペミスではない。

正直なところ`age`の昇順になると思った。これはインデックスから計算されているためでどうのこうの書こうとしたが、もう何も書けない。

この挙動について説明できる方がいたら是非コメントしていただきたい。

理由についてしっかりと言及できなかったが、できようができまいが結論は同じだ。
レコードを複数件取得する場合はORDER BYを絶対に指定して。


例題5

最後にもう1題。

SELECT
  id,
  age
FROM
  users
;





結果は以下のようになる。



+----+------+
| id | age  |
+----+------+
| 11 |    9 |
|  3 |   22 |
|  7 |   24 |
|  1 |   25 |
| 10 |   26 |
|  6 |   27 |
|  4 |   28 |
|  9 |   29 |
|  2 |   30 |
|  8 |   33 |
|  5 |   35 |
+----+------+
11 rows in set (0.00 sec)

あなたは全ての例題に正解を出せただろうか。
何問正解できたかコメントいただけると嬉しい。





宣伝(他にこんな記事を書いています)



いいなと思ったら応援しよう!