【SQL】ORDER BYの活用いろいろ | 若手エンジニアのブログ

若手エンジニアのブログ

文系出身の若手女子エンジニアによる技術ブログ。
日々の経験や学びをアウトプットするためにブログを書いています。
バックエンド(Java+SpringFramework)を経てインフラエンジニアになりました。
今は育休中につき、本で勉強したことを中心にアウトプットしています。

再びSQLの勉強シリーズに戻ります(`・ω・´)

今日はORDER BY句。

役割は知っているけれど、細かなルールについても分かっておきたいなあと思い、改めて勉強してみます。

 

もくじ

1.ORDER BY句とは

2.昇順ソート/降順ソート

3.指定カラムにNULLが含まれる場合のソート

4.UNIONを含むソート

 

 

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については、別の機会に改めて記事にしたいと思います。