SQL ORDER BYでレコードを並び替えるときのポイント
ORDER BYでレコードを並び替える時の注意点とポイントをまとめます。
以下のようなテーブルがあるとします。
| id | first_name | last_name | height | 
|---|---|---|---|
| 1 | 一郎 | 山田 | 175 | 
| 2 | 次郎 | 佐藤 | 175 | 
| 3 | 三郎 | 田中 | 185 | 
| 4 | 四郎 | 鈴木 | 155 | 
身長の降順(大きい順)、身長が同じ時はidの昇順(小さい順)で並び替えたいときは、以下のようなSQLになります。
SELECT
  id
  ,first_name
  ,last_name
  ,height
FROM
  employee
ORDER BY
  height DESC
  ,id| id | first_name | last_name | height | 
|---|---|---|---|
| 3 | 三郎 | 田中 | 185 | 
| 1 | 一郎 | 山田 | 175 | 
| 2 | 次郎 | 佐藤 | 175 | 
| 4 | 四郎 | 鈴木 | 155 | 
ORDER BY句で並び替えたい列名を指定します。
列名のあとにASCで昇順、DESCで降順でのソートになります。ASCは省略可能です。
ソート順が一意になるまで指定する
ORDER BYで指定した列の値がすべて同じ場合はどのような順番で取得されるのか定まりません。
上記例では、身長が同じデータ(idが1と2のデータ)がありますが、その場合は2つ目に指定した列(id)で並び替えが行われます。
「身長順で出力してください。」という仕様でも、身長が同じ場合というのは考えられますので、指定したソート順が一意となるまで、2つ目以降にも列を指定してするべきです。(本当は仕様を決める段階で一意になるように考慮するべきですが、できていない場合が多いです)
数字と文字列のソートの違い
データベースの列の定義が数値型か文字列型かで、ソート結果が異なるので注意が必要です。
数値型のnumber_idと文字列型のstring_idを持つテーブルがあるとします。
| number_id | string_id | 
|---|---|
| 1 | 1 | 
| 2 | 2 | 
| 10 | 10 | 
| 11 | 11 | 
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)OracleはTO_NUMBERで文字列を数値に変換しますが、数値に変換できない文字列("abc"など)の場合はエラーが発生してしまいます。
数値しか登録されていないということが保証されている必要があります。(数値しか登録されないのなら列定義を数値型にするべきだとは思いますが。。)