SQL道場 行を並び替え(ソート)する方法
ORDER BY句で指定した列により並び替え(ソート)する方法や数値のソート結果がおかしい場合の対処方法なども記載
環境
使用ツール:Microsoft SQL Server Management Studio MySQL Workbench
テーブル設計図
SQLServer

MySQL

ORDER BYの文法
ORDER BY 列名 [ASC or DESC] ,列名2 [ASC or DESC] ,・・・・
昇順に並べる場合は「ASC」を指定します。ASC、DESCを省略した場合はASCと見なされます。列の内容が数字の場合は小さいものから大きいものの順に並びます。文字列の場合は文字コードの小さいものから大きいものの順に並びます。
降順に並べる場合は「DESC」を指定します。列の内容が数字の場合は数値の大きいものから小さいものの順に並びます。文字列の場合は文字コードの大きいものから小さいものの順に並びます。
指定した列を使ってレコードを昇順(ASC)に並び替える
対応:SQL Server MySQL Oracle PostgreSQL DB2 SQLite Access ANSI
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルに格納されているデータを年齢の若い順(昇順)にレコードを並べ替えるSQLです。ここではASCを指定していますが、省略することができます。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 年齢が若い順にレコードを並び替える */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] ORDER BY EMP_AGE ASC;

MySQL
/* 年齢が若い順にレコードを並び替える */
SELECT * FROM testdb.MST_EMPLOYEE ORDER BY EMP_AGE ASC;

指定した列を使ってレコードを降順(DESC)に並び替える
対応:SQL Server MySQL Oracle PostgreSQL DB2 SQLite Access ANSI
実行結果
「MST_EMPLOYEE(社員マスタ)」テーブルに格納されているデータを年齢が高い順(降順)にレコードを並べ替えるSQLです。
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 年齢が高い順にレコードを並び替える */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] ORDER BY EMP_AGE DESC;

MySQL
/* 年齢が高い順にレコードを並び替える */
SELECT * FROM testdb.MST_EMPLOYEE ORDER BY EMP_AGE DESC;

複数の列を使用してレコードを並び替える
複数の列を使用して並び替えしたいシーンがあります。例えば、同じ部署内で男性の年齢が若い順にしたい等。その場合は、ORDER BY句に複数の列を列挙することで並び替えることができます。
例えば、部署コード(第1)、性別(第2)、年齢(第3)とORDER BY句に指定します。まずは、第1で指定した列で並び替えをします。次に第2で指定した列の値で第1で並び替えをした結果に対して並び替えをします。指定した列分レコードを並び替えしていきます。下の図のような並び替えの挙動になります。

実行結果
ID | EMP_NAME(社員名) | EMP_NAME_KANA(社員カナ) | EMP_DEPTCD(部署コード) | EMP_AGE(年齢) | EMP_SEX(性別) | ENABLE(有効区分) |
---|---|---|---|---|---|---|
1 | すなりん 太郎 | すなりん たろう | 1 | 35 | 男 | 1 |
2 | 博多 ぴーち | はかた ぴーち | 2 | 20 | 女 | 1 |
3 | 田中 工事 | たなか こうじ | 2 | 26 | 男 | 1 |
4 | 佐々木 花子 | ささき はなこ | 1 | 40 | 女 | 1 |
5 | 佐藤 じゅん | さとう じゅん | 1 | 23 | 1 | |
6 | 佐々木 ゆん | ささき ゆん | 1 | 23 | 1 |
SQL Server
/* 複数の列を指定して並び替えを行う */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] ORDER BY EMP_DEPTCD ASC, EMP_SEX ASC, EMP_AGE ASC;

MySQL
/* 複数の列を指定して並び替えを行う */
SELECT * FROM testdb.MST_EMPLOYEE ORDER BY EMP_DEPTCD ASC, EMP_SEX ASC, EMP_AGE ASC;

数値のソート結果がおかしい
ソート結果が意図しないことがあります。例えば年齢が数値型ではなく文字列型などになっていた場合、小さい順にソートした年齢が「20、25、3、30、4」のようにソートされてしまいます。


列のデータ型を数値タイプに変更すれば問題を解決することもできますが、開発経験において運用フェーズまで進んでしまったシステムではデータ型を変更した場合、障害を起こすケースがあるので安易に変更できません。
そこで、CAST関数を使用して年齢をUNSIGNEDを指定して文字を数値としてソートさせます。※SQL Serverはintになります。
SQL Server
/* 複数の列を指定して並び替えを行う */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE2] ORDER BY CAST(EMP_AGE as int) ASC;

MySQL
/* データ型を数値タイプに変更 */
SELECT * FROM testdb.MST_EMPLOYEE ORDER BY CAST(EMP_AGE AS UNSIGNED) ASC;

型変換しないソート方法
文字列の左側に「前ゼロ(ゼロパディング)」を付加して桁を合わせる方法もあります。先頭に「00」を付加して右から3桁抽出しています。
SQL Server
/* 数値型に変換しない方法 */
SELECT RIGHT(CONCAT('00',EMP_AGE),3) FROM [SampleDB].[dbo].[MST_EMPLOYEE2] ORDER BY RIGHT(CONCAT('000',EMP_AGE),3);

MySQL
/* データ型を数値がたに変換しない方法 */
SELECT RIGHT(CONCAT('00',EMP_AGE),3) FROM testdb.MST_EMPLOYEE ORDER BY RIGHT(CONCAT('000',EMP_AGE),3);
