SQL道場 行を並び替え(ソート)する方法

ORDER BY句で指定した列により並び替え(ソート)する方法や数値のソート結果がおかしい場合の対処方法なども記載

環境

使用ツール:Microsoft SQL Server Management Studio MySQL Workbench

テーブル設計図

SQLServer

SQLServerサンプル用のテーブル設計図

MySQL

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を指定していますが、省略することができます。

IDEMP_NAME(社員名)EMP_NAME_KANA(社員カナ)EMP_DEPTCD(部署コード)EMP_AGE(年齢)EMP_SEX(性別)ENABLE(有効区分)
1すなりん 太郎すなりん たろう1351
2博多 ぴーちはかた ぴーち2201
3田中 工事たなか こうじ2261
4佐々木 花子ささき はなこ1401
5佐藤 じゅんさとう じゅん1231
6佐々木 ゆんささき ゆん1231

SQL Server

/* 年齢が若い順にレコードを並び替える */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] ORDER BY EMP_AGE ASC;
ORDER BY ASCのサンプル結果(SQL SERVER)

MySQL

/* 年齢が若い順にレコードを並び替える */
SELECT * FROM testdb.MST_EMPLOYEE ORDER BY EMP_AGE ASC;
ORDER BY ASCのサンプル結果(MYSQL SERVER)

指定した列を使ってレコードを降順(DESC)に並び替える

対応:SQL Server MySQL Oracle PostgreSQL DB2 SQLite Access ANSI

実行結果

「MST_EMPLOYEE(社員マスタ)」テーブルに格納されているデータを年齢が高い順(降順)にレコードを並べ替えるSQLです。

IDEMP_NAME(社員名)EMP_NAME_KANA(社員カナ)EMP_DEPTCD(部署コード)EMP_AGE(年齢)EMP_SEX(性別)ENABLE(有効区分)
1すなりん 太郎すなりん たろう1351
2博多 ぴーちはかた ぴーち2201
3田中 工事たなか こうじ2261
4佐々木 花子ささき はなこ1401
5佐藤 じゅんさとう じゅん1231
6佐々木 ゆんささき ゆん1231

SQL Server

/* 年齢が高い順にレコードを並び替える */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] ORDER BY EMP_AGE DESC;
ORDER BY DESCのサンプル結果(SQL SERVER)

MySQL

/* 年齢が高い順にレコードを並び替える */
SELECT * FROM testdb.MST_EMPLOYEE ORDER BY EMP_AGE DESC;
ORDER BY DESCのサンプル結果(MYSQL SERVER)

複数の列を使用してレコードを並び替える

複数の列を使用して並び替えしたいシーンがあります。例えば、同じ部署内で男性の年齢が若い順にしたい等。その場合は、ORDER BY句に複数の列を列挙することで並び替えることができます。

例えば、部署コード(第1)、性別(第2)、年齢(第3)とORDER BY句に指定します。まずは、第1で指定した列で並び替えをします。次に第2で指定した列の値で第1で並び替えをした結果に対して並び替えをします。指定した列分レコードを並び替えしていきます。下の図のような並び替えの挙動になります。

並び替え(ソート)の挙動解説図

実行結果

IDEMP_NAME(社員名)EMP_NAME_KANA(社員カナ)EMP_DEPTCD(部署コード)EMP_AGE(年齢)EMP_SEX(性別)ENABLE(有効区分)
1すなりん 太郎すなりん たろう1351
2博多 ぴーちはかた ぴーち2201
3田中 工事たなか こうじ2261
4佐々木 花子ささき はなこ1401
5佐藤 じゅんさとう じゅん1231
6佐々木 ゆんささき ゆん1231

SQL Server

/* 複数の列を指定して並び替えを行う */
SELECT * FROM [SampleDB].[dbo].[MST_EMPLOYEE] ORDER BY EMP_DEPTCD ASC, EMP_SEX ASC, EMP_AGE ASC;
ORDER BY 複数列指定のサンプル結果(SQL SERVER)

MySQL

/* 複数の列を指定して並び替えを行う */
SELECT * FROM testdb.MST_EMPLOYEE ORDER BY EMP_DEPTCD ASC, EMP_SEX ASC, EMP_AGE ASC;
ORDER BY 複数列指定のサンプル結果(MSQL)

数値のソート結果がおかしい

ソート結果が意図しないことがあります。例えば年齢が数値型ではなく文字列型などになっていた場合、小さい順にソートした年齢が「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;
数値型に変換する方法(SQL SERVER)

MySQL

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

型変換しないソート方法

文字列の左側に「前ゼロ(ゼロパディング)」を付加して桁を合わせる方法もあります。先頭に「00」を付加して右から3桁抽出しています。

SQL Server

/* 数値型に変換しない方法 */
SELECT RIGHT(CONCAT('00',EMP_AGE),3) FROM [SampleDB].[dbo].[MST_EMPLOYEE2] ORDER BY RIGHT(CONCAT('000',EMP_AGE),3);
数値型に変換しない方法、RIGHTとCONCATを使用する方法(SQL SERVER)

MySQL

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