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"
など)の場合はエラーが発生してしまいます。
数値しか登録されていないということが保証されている必要があります。(数値しか登録されないのなら列定義を数値型にするべきだとは思いますが。。)