SQLの昇順ソート指定についてまとめています。
SQLの昇順指定は、order byでasc指定を行う。
SQLのソートで、昇順指定をするにはorder byでカラム名の後にascをつけます。なお、ascを省略した場合も昇順指定とみなされます。デフォルトのソート順が昇順なんですね。
以下の例は、emp_no(社員番号)でemployees(社員)テーブルをソートしてselectした例です。
mysql> select * from employees order by emp_no asc; +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 | | 10002 | 1964-06-02 | Bezalel | Simmel | F | 1985-11-21 | | 10003 | 1959-12-03 | Parto | Bamford | M | 1986-08-28 | | 10004 | 1954-05-01 | Chirstian | Koblick | M | 1986-12-01 | | 10005 | 1955-01-21 | Kyoichi | Maliniak | M | 1989-09-12 | | 10006 | 1953-04-20 | Anneke | Preusig | F | 1989-06-02 | | 10007 | 1957-05-23 | Tzvetan | Zielinski | F | 1989-02-10 | | 10008 | 1958-02-19 | Saniya | Kalloufi | M | 1994-09-15 | | 10009 | 1952-04-19 | Sumant | Peac | F | 1985-02-18 | | 10010 | 1963-06-01 | Duangkaew | Piveteau | F | 1989-08-24 | +--------+------------+------------+-----------+--------+------------+
【関連記事】
▶SQL order byでソート指定するサンプルコード集 指定のレコードだけ先頭に並べるには?
文字列ソート時は、照合順序設定に従ってソートされる
文字列を昇順ソートすると、以下のようになります。first_name(姓名の名)で昇順ソートしているので、Aで始まるAamerが一番に出てきているんですね。
mysql> select * from employees order by first_name asc; +--------+------------+------------+-------------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-------------+--------+------------+ | 11935 | 1963-03-23 | Aamer | Jayawardene | M | 1996-10-26 | | 13011 | 1955-02-25 | Aamer | Glowinski | F | 1989-10-08 | | 22279 | 1959-01-30 | Aamer | Kornyak | M | 1985-02-25 | | 20678 | 1963-12-25 | Aamer | Parveen | F | 1987-03-25 | | 23269 | 1952-02-15 | Aamer | Szmurlo | M | 1988-05-25 | | 12160 | 1954-12-11 | Aamer | Garrabrants | M | 1989-09-19 | | 24404 | 1960-04-21 | Aamer | Tsukuda | M | 1998-12-25 | | 11800 | 1958-12-09 | Aamer | Fraisse | M | 1990-08-08 | | 28043 | 1957-07-13 | Aamer | Kroll | F | 1986-05-17 | | 15332 | 1961-12-29 | Aamer | Slutz | F | 1989-05-19 | : :
日本語などのマルチバイト文字の場合は、Collationと呼ばれる照合順序の設定に従ってソートされます。
select * from employees order by birth_date; +--------+------------+------------+--------------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+--------------+--------+------------+ | 207658 | 1952-02-01 | Kiyokazu | Whitcomb | M | 1988-07-26 | | 87461 | 1952-02-01 | Moni | Decaestecker | M | 1986-10-06 | | 65308 | 1952-02-01 | Jouni | Pocchiola | M | 1985-03-10 | | 406121 | 1952-02-01 | Supot | Remmele | M | 1989-01-27 | | 91374 | 1952-02-01 | Eishiro | Kuzuoka | M | 1992-02-12 | | 237571 | 1952-02-01 | Ronghao | Schaad | M | 1988-07-10 | | 33131 | 1952-02-02 | Reinhold | Savasere | M | 1998-01-30 | | 51486 | 1952-02-02 | Jianwen | Sigstam | F | 1989-07-20 | | 61382 | 1952-02-02 | Kristof | Ranft | M | 1989-04-21 | | 59884 | 1952-02-02 | Fan | Przulj | M | 1991-09-25 |
MySQLの場合は、以下のSQLでデータベースemployeesのデフォルトキャラクターセット(DEFAULT_CHARACTER_SET_NAME)と、デフォルトの照合順序(DEFAULT_COLLATION_NAME )を確認できます。
mysql> select DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME from INFORMATION_SCHEMA.SCHEMATA where schema_name='employees'; +----------------------------+------------------------+ | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | +----------------------------+------------------------+ | utf8mb4 | utf8mb4_0900_ai_ci | +----------------------------+------------------------+ 1 row in set (0.00 sec)
照合順序(COLLATION)は、命名規則に従って名前がついているので、名前からある程度照合順序の内容がわかります。
- _ai アクセントに影響されない
- _as アクセントに敏感
- _ci 大文字小文字を区別しない
- _cs 大文字と小文字を区別
- _ks かなに敏感
- _bin バイナリ
引用:MySQL :: MySQL8.0リファレンスマニュアル:: 10.3.1照合命名規則
utf8mb4_0900_ai_ciは、「アクセントに影響されない」「大文字小文字を区別しない」「ひらがなカタカナを区別しない」照合順序となります。
そのため、日本語で「ぱ」と「ば」が区別されない、「あ」と「ぁ」が区別されない、「ア」と「あ」が区別されないということになります。そのため、一見すると「なんだかランダムにソートされてるような気がする…」ように見えてしまうんですね。
厳密にソートしたいなら、「バイナリ」を使うと良いでしょう。show collationで、利用可能なcollationを検索可能です。下記の場合、utf8mb4_0900_bin が、バイナリでの照合順序になります。
show collation like 'utf8mb4_0900%'; +--------------------+---------+-----+---------+----------+---------+---------------+ | Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute | +--------------------+---------+-----+---------+----------+---------+---------------+ | utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 0 | NO PAD | | utf8mb4_0900_as_ci | utf8mb4 | 305 | | Yes | 0 | NO PAD | | utf8mb4_0900_as_cs | utf8mb4 | 278 | | Yes | 0 | NO PAD | | utf8mb4_0900_bin | utf8mb4 | 309 | | Yes | 1 | NO PAD | +--------------------+---------+-----+---------+----------+---------+---------------+ 4 rows in set (0.00 sec)
なお、照合順序はデータベースやテーブルごとに設定可能です。データベースに対して設定するには、create databaseまたは、alter databaseにてcollate項目を設定します。
以下は、employeesデータベースのデフォルトキャラクターセットと照合順序を確認し、alter databaseでデフォルトの照合順序をutf8mb4_0900_binに変更する例です。
mysql> select DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME from INFORMATION_SCHEMA.SCHEMATA where schema_name='employees'; +----------------------------+------------------------+ | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | +----------------------------+------------------------+ | utf8mb4 | utf8mb4_0900_ai_ci | +----------------------------+------------------------+ 1 row in set (0.00 sec) mysql> alter database employees collate 'utf8mb4_0900_bin'; Query OK, 1 row affected (0.06 sec) mysql> select DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME from INFORMATION_SCHEMA.SCHEMATA where schema_name='employees'; +----------------------------+------------------------+ | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | +----------------------------+------------------------+ | utf8mb4 | utf8mb4_0900_bin | +----------------------------+------------------------+ 1 row in set (0.00 sec)
ソート指定にはカラムごとに昇順、降順の混在が可能
mysql> SELECT * FROM `employees` ORDER BY first_name, hire_date ASC, emp_no DESC; +--------+------------+------------+-----------+--------+------------+ | emp_no | birth_date | first_name | last_name | gender | hire_date | +--------+------------+------------+-----------+--------+------------+ | 22279 | 1959-01-30 | Aamer | Kornyak | M | 1985-02-25 | | 217381 | 1962-04-28 | Aamer | Pocchiola | M | 1985-03-01 | | 235609 | 1955-02-10 | Aamer | Talmor | M | 1985-03-11 | | 39647 | 1953-01-01 | Aamer | Massonet | F | 1985-03-12 | | 86639 | 1953-11-12 | Aamer | Yavatkar | M | 1985-03-16 | | 423197 | 1957-08-15 | Aamer | Madeira | F | 1985-03-17 | | 497615 | 1954-11-18 | Aamer | McDermid | M | 1985-04-24 | | 230243 | 1956-01-05 | Aamer | Ullian | M | 1985-04-30 | | 213128 | 1961-04-15 | Aamer | Rosin | M | 1985-05-18 | | 498104 | 1954-04-03 | Aamer | Rosca | M | 1985-06-14 | : :
ソート指定では、昇順のascと降順のdesc指定の混在が可能です。省略した場合はasc(昇順)となります。上記の例では、、first_name昇順、hire_date昇順、emp_no 降順となります。
【関連記事】
▶SQLのdescはorder byソートの降順指定 テーブル定義表示もおこなう
まとめ
- 昇順でソートするには、order byでカラム名の後ろにascを指定
- 文字列のソートの場合、日本語などのマルチバイト文字は照合順序に従ってソートされる
- ソート指定には昇順、降順を混在可能