再びSQLの勉強シリーズに戻ります(`・ω・´)
今日はORDER BY句。
役割は知っているけれど、細かなルールについても分かっておきたいなあと思い、改めて勉強してみます。
もくじ
1.ORDER BY句とは
SELECTしてきたレコードを、昇順または降順に並び替える(ソートする)ときに利用する。
ORDER BYの後に、どのカラムで並び替えを行うかを指定する。
SELECT * FROM FRUITS_TABLE ORDER BY SHOP_ID;
よく使われる句であり、また基本情報(応用情報かも)でも頻出な処理である。
(ただしソート処理自体はDB負荷が大きいので乱用はよくない)
以下、様々な条件下でORDERN BYを利用するときの動作を、Oracle Database19cで確認した。
SELECT * FROM FRUITS_TABLE ORDER BY SHOP_ID;
2.昇順ソート/降順ソート
・昇順でソートしたい場合
ORDER BY句のカラム指定後に、ASCキーを記述する。
ただしデフォルトでは昇順ソートとなる。ので、キーを省略した場合も、昇順となる。
SQL> SELECT * FROM FRUITS_TABLE ORDER BY SHOP_ID ASC;
ID FRUIT_NAME SHOP_ID
---------- ---------- ----------
2 banana 2
1 apple 2
3 orange 2
5 grape 4
6 test 5
以下も同じ結果となる。
SQL> SELECT * FROM FRUITS_TABLE ORDER BY SHOP_ID;
ID FRUIT_NAME SHOP_ID
---------- ---------- ----------
2 banana 2
1 apple 2
3 orange 2
5 grape 4
6 test 5
・降順でソートしたい場合
ASCキーの代わりに、DESCキーを付与する。
昇順ソートとは違い、キーを省略すると降順にならないので、明示的に指定してやる必要がある。
SQL> SELECT * FROM FRUITS_TABLE ORDER BY SHOP_ID DESC;
ID FRUIT_NAME SHOP_ID
---------- ---------- ----------
5 grape 4
2 banana 2
1 apple 2
3 orange 2
4 chery 1
・A列では昇順、B列では降順でソートしたい場合
以下のように、「,」(コンマ)で区切って、複数指定することができる。
先に指定したソートのほうが、より優先される。
SQL> SELECT * FROM FRUITS_TABLE ORDER BY SHOP_ID DESC, ID ASC;
ID FRUIT_NAME SHOP_ID
---------- ---------- ----------
5 grape 4
1 apple 2
2 banana 2
3 orange 2
4 chery 1
3.指定カラムにNULLが含まれる場合のソート
昇順なら最後に、降順なら最初に、指定列がNULLとなるレコードが来る。
SQL> SELECT * FROM FRUITS_TABLE ORDER BY SHOP_ID ASC;
ID FRUIT_NAME SHOP_ID
---------- ---------- ----------
4 chery 1
2 banana 2
3 orange 2
1 apple 2
5 grape 4
6 test 5
7 peach ←NULLの列が最後
SQL> SELECT * FROM FRUITS_TABLE ORDER BY SHOP_ID DESC;
ID FRUIT_NAME SHOP_ID
---------- ---------- ----------
7 peach ←NULLの列が最初
5 grape 4
1 apple 2
2 banana 2
3 orange 2
4 chery 1
4.UNIONを含むソート
UNIONもしくはUNION ALLを含む場合、結果を結合した最後に、結果全体に対してソートを行う流れとなる。
各副問合せで独自ソートはできない。(もし独自ソートできたとしたら、結果がごちゃごちゃになりそう…)
クエリ全体としても、以下のように、最後にORDER BY句を指定することになる。
SQL> SELECT SHOP_ID AS ID FROM FRUITS_TABLE
UNION
SELECT ID FROM SHOPS_TABLE ORDER BY ID;
ID
----------
1
2
3
4
5
また、ORDER BY句で指定する列名は、1つ目の副問合せの列名とするか、
UNION結合前にASでそろえた名称とする必要がある。
上記の例では、1つ目の副問合せのほうに、ASによって「ID」という名称を付与している。
もしASで名称を統一しなかった場合、以下のように、ソート対象の列名が見つからないエラーとなる。
SQL> SELECT SHOP_ID FROM FRUITS_TABLE
UNION
SELECT ID FROM SHOPS_TABLE ORDER BY ID;
SELECT ID FROM SHOPS_TABLE ORDER BY ID
*
ERROR at line 3:
ORA-00904: "ID": invalid identifier
ただし、1つ目の副問合せで用いた列名であれば、2つ目以降の副問合せにASを指定しなくてもソートされる。(可読性が下がるので指定しておいたほうが良いとは思う)
SQL> SELECT SHOP_ID FROM FRUITS_TABLE
UNION
SELECT ID FROM SHOPS_TABLE ORDER BY SHOP_ID;
SHOP_ID
----------
1
2
3
4
5
なお、各副問合せで、列名がもとから同じなのであれば、ASでわざわざ合わせなくてよい。
もちろん以下のように、まったく異なる列名をASで指定しても良い。
SQL> SELECT SHOP_ID AS TEST_ID FROM FRUITS_TABLE
UNION
SELECT ID AS TEST_ID FROM SHOPS_TABLE ORDER BY TEST_ID;
TEST_ID
----------
1
2
3
4
5
UNIONを含むソートについて、ここまでの内容をまとめると、以下のようになる。
■各副問合せで、ソート対象の列名が異なる場合
・1つ目の副問合せの列名でソート
→2つ目の副問合せの列名変更は不要(ただし明示したほうが分かりやすい)
・2つ目の副問合せの列名でソート
→1つ目の副問合せの列名変更が必要
・全く異なる列名としてソート
→1つ目、2つ目とも列名変更が必要
■各副問合せで、ソート対象の列名が同じ場合
・列名変更は不要(変更してもよい)
今回は以上!
副問合せやUNIONについては、別の機会に改めて記事にしたいと思います。