ORDER BY 句の使い方
shain社員
| name | salary |
|---|---|
| 鈴木 | 980000 |
| 佐藤 | 720000 |
| 田中 | 520000 |
| 中村 | 530000 |
| 小林 | 445050 |
| 加藤 | 610000 |
| … | |
ORDER BY salary DESC並べ替えた結果
| name | salary |
|---|---|
| 鈴木 | 980000 |
| 佐藤 | 720000 |
| 山田 | 700000 |
| 清水 | 650000 |
| 加藤 | 610000 |
| 中村 | 530000 |
| … | |
ORDER BY salary DESC
- 行は 1 つも減りません。並び順だけが変わります(左右で同じ 18 行)
並べ替えは行を捨てません。左右で行数は同じです。行を減らすのは WHERE や LIMIT の仕事です。
ORDER BY は結果の並び順を決めます。いちばん大事な事実は、指定しなければ順番は保証されないということです。たまたま並んで見えても、それは偶然です。並びに意味があるなら必ず書いてください。
主要 7 製品で通用 そのまま使える: PostgreSQL / MySQL / MariaDB / SQLite / SQL Server / Oracle Database / IBM Db2
このページの実行結果と図は、すべて本物のデータベースに同じ SQL を流して得たものです。手で書いた「たぶんこうなる」ではありません。
01⚠️ 指定しなければ順番は保証されない
結論: `ORDER BY` が無い問い合わせの並び順は、決まっていません。
小さい表では登録順に見えることが多く、それで動いているように錯覚します。しかし表が大きくなったり、索引が使われたり、処理が並列化されると順番は変わります。
「たまたま並んでいた」ものに依存した処理は、いつか必ず壊れます。 並びに意味があるなら必ず ORDER BY を書いてください。
SELECT name, salary何を出すかFROM shainどの表を見るかWHERE taishoku_on IS NULLどの行を残すかORDER BY salary DESC,第 1 キー(高い順)shain_id第 2 キー(同額のときの決着)
ORDER BY は最後に効きます。だから SELECT で付けた別名も使えます。
SELECT name, salary FROM shain;| name | salary |
|---|---|
| 鈴木 | 980000 |
| 佐藤 | 720000 |
| 田中 | 520000 |
| 中村 | 530000 |
| 小林 | 445050 |
(18 行 … うち先頭 5 行を表示)
この環境では登録順に見えますが、これは保証された動きではありません。
SELECT name, salary FROM shain ORDER BY salary DESC;| name | salary |
|---|---|
| 鈴木 | 980000 |
| 佐藤 | 720000 |
| 山田 | 700000 |
| 清水 | 650000 |
| 加藤 | 610000 |
(18 行 … うち先頭 5 行を表示)
DESC で降順です。省略すると昇順(ASC)になります。
02同じ値のときをどう決めるか
結論: 第 1 キーが同じ行の並びは、第 2 キーを書かないと決まりません。
この表には給与が同額の社員が 2 人います。ORDER BY salary DESC だけでは、その 2 人のどちらが先に来るかが決まっていません。
ページ送り(`LIMIT` と `OFFSET`)を使うときは特に危険です。 順番が実行のたびに変われば、同じ行が 2 度出たり、逆に抜け落ちたりします。一意な列を最後のキーに足しておくと安全です。
SELECT name, salary FROM shain WHERE salary = 530000 ORDER BY salary DESC;| name | salary |
|---|---|
| 中村 | 530000 |
| 伊藤 | 530000 |
(2 行)
この 2 人の順番は、第 1 キーだけでは決まりません。
SELECT shain_id, name, salary FROM shain ORDER BY salary DESC, shain_id;| shain_id | name | salary |
|---|---|---|
| 1 | 鈴木 | 980000 |
| 2 | 佐藤 | 720000 |
| 8 | 山田 | 700000 |
| 14 | 清水 | 650000 |
| 6 | 加藤 | 610000 |
| 4 | 中村 | 530000 |
| 10 | 伊藤 | 530000 |
| 3 | 田中 | 520000 |
(18 行 … うち先頭 8 行を表示)
shain_id は一意なので、これで並びが 1 通りに決まります。何度実行しても同じ順番です。
03式や別名でも並べられる
結論: `ORDER BY` には列名だけでなく、式も `SELECT` で付けた別名も書けます。
ORDER BY は SELECT のあとに評価されるため、そこで作った名前をそのまま使えます(WHERE では使えません)。
CASE を書けば、文字コード順とは関係のない業務上の並びも作れます。ステータスの重要度順などはこの形で表現します。
SELECT name, salary * 12 AS nenshu FROM shain ORDER BY nenshu DESC, name LIMIT 5;| name | nenshu |
|---|---|
| 鈴木 | 11760000 |
| 佐藤 | 8640000 |
| 山田 | 8400000 |
| 清水 | 7800000 |
| 加藤 | 7320000 |
(5 行)
SELECT で付けた nenshu を、そのまま並べ替えのキーにできます。
⚠️ この書き方は SQL Server / Oracle Database / IBM Db2 では使えません(LIMIT n)。製品ごとの対応表
SELECT name, hired_on FROM shain ORDER BY EXTRACT(YEAR FROM hired_on), name LIMIT 6;| name | hired_on |
|---|---|
| 清水 | 2013-04-01 |
| 鈴木 | 2014-04-01 |
| 山田 | 2015-04-01 |
| 佐藤 | 2016-10-01 |
| 山本 | 2016-04-01 |
| 伊藤 | 2017-04-01 |
(6 行)
並べ替えのキーに使った式は、結果に出さなくても構いません。
⚠️ この書き方は SQLite / SQL Server / Oracle Database / IBM Db2 では使えません(EXTRACT(日付の一部を取り出す))。製品ごとの対応表
04⚠️ 文字列の並び順は「照合順序」で決まる
結論: 文字列の大小は、その列の照合順序(collation)が決めます。
数値や日付は誰が見ても大小が同じですが、文字列は違います。大文字と小文字をどう扱うか、記号や空白をどう並べるかは、照合順序の設定で変わります。
日本語では特に注意が要ります。多くの環境で、漢字は「読み」ではなく文字コード順に並びます。「五十音順に並べたい」なら、読み仮名の列を別に持って、そちらで並べるのが確実です。
同じ SQL でも、環境の照合順序が違えば並び順が変わります。エラーにならない差なので、並びに意味があるなら、どの照合順序で動いているかを確かめてください。
SELECT name FROM shain ORDER BY name;| name |
|---|
| 中村 |
| 井上 |
| 伊藤 |
| 佐藤 |
| 加藤 |
| 吉田 |
| 大野 |
| 小林 |
(18 行 … うち先頭 8 行を表示)
五十音順ではなく文字コード順に並んでいます。日本語を「読み」で並べたいなら、読みを別の列に持つ必要があります。
SELECT busho_name FROM busho ORDER BY busho_name;| busho_name |
|---|
| マーケ |
| 営業 |
| 基盤 |
| 法務 |
| 管理 |
| 経営 |
| 開発 |
(7 行)
並んではいますが、この順序に業務上の意味はありません。意味のある順に並べたいなら、CASE で明示するか並び順の列を持ちます。
05⚠️ NULL をどこに置くかは製品で違う
結論: NULL の位置は SQL の規格では決まっておらず、製品ごとの既定に従います。
PostgreSQL は昇順で最後・降順で最初、MySQL は逆に昇順で最初に来ます。同じ SQL が製品によって違う順番を返す、というエラーにならない差です。
位置に意味があるなら NULLS FIRST / NULLS LAST で明示してください。⚠️ ただしこの書き方は MySQL・MariaDB・SQL Server にはありません。それらでは並べ替えのキーに 列 IS NULL を足して代用します。
SELECT name, busho_id FROM shain ORDER BY busho_id;| name | busho_id |
|---|---|
| 鈴木 | 1 |
| 佐藤 | 2 |
| 田中 | 2 |
| 中村 | 2 |
| 小林 | 2 |
| 山田 | 3 |
(18 行 … うち先頭 6 行を表示)
PostgreSQL では昇順のとき NULL が最後に来ます。他の製品では違うことがあります。
SELECT name, busho_id FROM shain ORDER BY busho_id NULLS FIRST, shain_id;| name | busho_id |
|---|---|
| 渡辺 | NULL |
| 大野 | NULL |
| 鈴木 | 1 |
| 佐藤 | 2 |
| 田中 | 2 |
(18 行 … うち先頭 5 行を表示)
位置を明示すれば、既定に頼らずに済みます。部署未定の社員が先頭に来ました。
⚠️ この書き方は MySQL / MariaDB / SQL Server では使えません(ORDER BY ... NULLS LAST)。製品ごとの対応表
SELECT name, busho_id FROM shain ORDER BY (busho_id IS NULL), busho_id, shain_id;| name | busho_id |
|---|---|
| 鈴木 | 1 |
| 佐藤 | 2 |
| 田中 | 2 |
| 中村 | 2 |
| 小林 | 2 |
(18 行 … うち先頭 5 行を表示)
IS NULL は真のとき大きい値として扱われるので、これで NULL が最後に来ます。どの製品でも通る書き方です。
自分で打ってみる
このページの例と同じデータが入った本物のデータベースを、この場(あなたのブラウザの中)で起動できます。打った SQL がサーバーへ送られることはありません。
押すと初回だけ約 9MB を読み込みます(2 回目以降はキャッシュされます)。
解いてみる
読んだだけでは書けるようになりません。実行結果で採点します。
関連するトピック
- LIMIT / FETCH FIRST件数を絞るときは、並び順が決まっていないと結果が安定しません。
- SELECT 句ORDER BY は SELECT のあとに評価されるので、別名が使えます。
- IS NULLNULL の位置を自分で決めるときに使います。
根拠(一次情報)
- PostgreSQL 18 マニュアル: 行の並べ替え一次情報・確認 2026-08-02
- PostgreSQL 18 マニュアル: SELECT(ORDER BY 句)一次情報・確認 2026-08-02