zukucode
主にWEB関連の情報を技術メモとして発信しています。

SQL ORDER BYでレコードを並び替えるときのポイント

ORDER BYでレコードを並び替える時の注意点とポイントをまとめます。

以下のようなテーブルがあるとします。

employee(社員)
idfirst_namelast_nameheight
1一郎山田175
2次郎佐藤175
3三郎田中185
4四郎鈴木155

身長の降順(大きい順)、身長が同じ時はidの昇順(小さい順)で並び替えたいときは、以下のようなSQLになります。

SELECT
  id
  ,first_name
  ,last_name
  ,height
FROM
  employee
ORDER BY
  height DESC
  ,id
取得結果
idfirst_namelast_nameheight
3三郎田中185
1一郎山田175
2次郎佐藤175
4四郎鈴木155

ORDER BY句で並び替えたい列名を指定します。

列名のあとにASCで昇順、DESCで降順でのソートになります。ASCは省略可能です。

ソート順が一意になるまで指定する

ORDER BYで指定した列の値がすべて同じ場合はどのような順番で取得されるのか定まりません。

上記例では、身長が同じデータ(id12のデータ)がありますが、その場合は2つ目に指定した列(id)で並び替えが行われます。

「身長順で出力してください。」という仕様でも、身長が同じ場合というのは考えられますので、指定したソート順が一意となるまで、2つ目以降にも列を指定してするべきです。(本当は仕様を決める段階で一意になるように考慮するべきですが、できていない場合が多いです)

数字と文字列のソートの違い

データベースの列の定義が数値型か文字列型かで、ソート結果が異なるので注意が必要です。

数値型のnumber_idと文字列型のstring_idを持つテーブルがあるとします。

employee
number_idstring_id
11
22
1010
1111
SELECT
  number_id
FROM
  employee
ORDER BY
  number_id
取得結果
string_id
1
2
10
11
SELECT
  string_id
FROM
  employee
ORDER BY
  string_id
取得結果
string_id
1
10
11
2

数値型の列のソートは数値の大小でソートが行われますが、文字列型の列のソートは文字列の大小(五十音順)でソートが行われます。

文字列型の列を数値ソートする方法

文字列型の列を数値としてソートしたい場合は、以下のようにORDER BYで列を指定するときに、数値型に型変換する必要があります。(以下Oracleでの例になります)

SELECT
  string_id
FROM
  employee
ORDER BY
  TO_NUMBER(string_id)

OracleTO_NUMBERで文字列を数値に変換しますが、数値に変換できない文字列("abc"など)の場合はエラーが発生してしまいます。

数値しか登録されていないということが保証されている必要があります。(数値しか登録されないのなら列定義を数値型にするべきだとは思いますが。。)


関連記事

  • Oracle 文字列の中で指定した文字を削除する

    Oracleで文字列の中で指定した文字を削除する方法を紹介します。REPLACEを使用して削除したい文字をNULL(空文字)に置き換えることで削除します。Oracleは空文字をNULLとして扱うので、...


  • SQL GROUP BYで複数の行を集計して1行で取得する

    GROUP BY 列名で集約したい列を指定します。上記例の場合は部署ごとに集約したいのでdepartment_idを指定しています。GROUP BYで指定した列以外の列をSELECT句で取得したい場合...


  • SQL FROM句で複数のテーブルを結合するポイント

    FROM句では取得したいテーブルのテーブル名を指定します。複数のテーブルを結合する場合はまず結合したいテーブルをJOINのあとに指定します。そしてONのあとに結合条件を指定します。結合条件を指定せずに...


  • SQL DISTINCTで重複行を1行のみ表示する方法

    SELECTのあとにDISTINCTをつけると、同一のレコードを1行のみ取得するようになります。上記例ではid=1と4のレコードの取得結果は同じになるので、本来は2行出力されるはずのレコードが、DIS...


  • PostgreSQL 現在のシステム日付・時刻を取得する

    OracleのSYSDATEのように、PostgreSQLで現在のシステム日付や時刻を取得する方法を紹介します。YYYY/MM/DDやYYYY-MM-DDのように、date型を取得するにはCURREN...


  • SQL FROM句での副問合わせの基本的な考え方と注意点

    FROM句で副問合わせを行うと、SELECTした結果を1つのテーブルとして、他のテーブルと結合できます。SELECTした結果をVIEWとして予め定義しておくことができますが、FROM句で副問合わせでは...


  • PostgreSQL 日付の加算・減算を行う

    PostgreSQLで日付の加算・減算を行う方法を紹介します。日付型のカラムに対しては、数字の計算と同じ要領で行うことができます。YYYYMMDD形式などの文字列型のカラムの場合は、日付型に変換してか...


  • PostgreSQL ISNULLやNVLのようにNULLを判定する方法

    PostgreSQLでSQL ServerのISNULLやOracleのNVLのように、NULLの場合に別の値を取得するにはCOALESCEを使用します。使い方はISNULLやNVLと同じように、第一...


  • PL/SQL 変数を宣言して値を設定する

    PL/SQLで変数を宣言して値を設定する方法を紹介します。ASとBEGINの間で変数を宣言します。宣言と同時に値をセット(初期化)も可能です。変数への代入は=ではなく:=で行います。


  • PL/SQL TRUNCATE TABLEをストアドプロシージャに定義する

    PL/SQLでTRUNCATE処理をストアドプロシージャに定義する方法を紹介します。そのまま定義すると「記号TABLEが見つかりました。」のコンパイルエラーになってしまうので、動的SQLで定義します。