ORDER BYでソート
ORDER BYでソート とは
ORDER BY句を使って、SQLでデータをソートする方法を実践的に学びます。本レッスンでは、ORDER BYでソート の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
なぜ重要か
結果セットの並び順は、ユーザー体験を左右する重要な要素です。新着順、価格の安い順、人気順、五十音順。アプリの一覧画面の並びは、ほぼすべて SQL の ORDER BY で決まります。逆に言えば、ORDER BY を書かなければ並び順は不定です。同じクエリでも実行のたびに違う順番で返る可能性があり、アプリが「なんとなく動いていた」状態になります。
また、後で学ぶ LIMIT / OFFSET によるページングは、ORDER BY を組み合わせないと意味を成しません。ORDER BY は SQL を実務に使ううえで最低限の守りの一手です。
並び順が決まっていないクエリは、ページングや CSV エクスポートのときに「同じレコードが二度出現する」「行が抜ける」というバグを生みます。ユーザーから「リロードしたら表示が変わる」と報告されたら、まず ORDER BY の有無を確認するのがセオリーです。
ORDER BY を書かないクエリの並び順は「不定」です。同じ SQL でも実行のたびに順番が変わりうる、と覚えておくとページングのバグを未然に防げます。
構文の全体像
SQL クエリ
SELECT <列リスト>
FROM <テーブル>
WHERE <条件>
ORDER BY <列1> [ASC|DESC], <列2> [ASC|DESC], ...;ASC は昇順 (小さい順)、DESC は降順 (大きい順)。省略すると ASC になります。複数列を指定すると、第一キーで並べ、同点の中で第二キーで並べる「タイブレーク」が走ります。
処理の流れ
論理的には WHERE と SELECT の後に ORDER BY が走ります。だから SELECT で AS を付けた別名は、ORDER BY でも使えます。WHERE では使えなかったのと対照的です。
代表例
例 1 は、価格の安い順に商品を並べるケースです。
SQL クエリ
SELECT id, name, price
FROM products
ORDER BY price ASC;ASC は省略可能ですが、レビュー時に意図が伝わるよう明示する流派もあります。チームの規約に合わせます。
例 2 は、複数列でソートするケースです。
SQL クエリ
SELECT id, name, category, price
FROM products
ORDER BY category ASC, price DESC;第一キーが category、同じカテゴリ内では price の降順 (高い順) で並びます。カタログ画面で「カテゴリ別に並べて、各カテゴリ内では人気順」のような UI を作るときによく使います。
例 3 は、別名でソートするケースです。
SQL クエリ
SELECT name, salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;SELECT で計算した列を、そのまま ORDER BY のキーに使えます。ORDER BY salary * 12 DESC でも同じ結果になりますが、別名のほうが読みやすいです。
NULL の並び順
NULL は「不明」なので、本来は順序が決まりません。MySQL / TiDB は ASC で NULL が先、DESC で NULL が後に並びます。Postgres はデフォルトが逆で、
NULLS FIRST/NULLS LASTを明示して制御するのが標準です。データベースごとの挙動差は移行時の落とし穴になりやすいです。
パフォーマンス上の注意
ORDER BY はメモリ上でソートを行うため、大量データに対する
ORDER BY 列名はパフォーマンスを悪化させやすい操作です。検索画面でよくソートに使う列にはインデックスを張る、あるいは「並び順用のキャッシュテーブル」を作るなどの設計が必要になります。逆に小規模なテーブルなら気にしすぎず、可読性を優先しても問題ありません。
よくある勘違い
SQL クエリ
-- これは並び順を保証しない
SELECT name FROM employees;「主キー順に並ぶだろう」「INSERT した順に並ぶだろう」は、いずれも保証されません。順序が必要なら必ず ORDER BY を書きます。これを習慣化するだけで、本番のレポート不具合をかなり減らせます。
日本語ソートの落とし穴
日本語のソートは「五十音順」と「Unicode コードポイント順」が一致しません。MySQL / TiDB のデフォルトで
ORDER BY nameを書くと、ひらがな・カタカナ・漢字が思った通りに並ばないことが多いです。五十音順で並べたい場合は、ふりがな列を別途用意してORDER BY name_kanaのように並べるのが定石です。漢字を含む人名や商品名のソートでは、設計段階でふりがな列を用意するかどうかを決めておきます。
まとめ
- ORDER BY を書かないと並び順は不定。順序が必要なら必ず書く
- ASC / DESC を切り替えられる。デフォルトは ASC
- 複数列指定でタイブレーク、SELECT の AS 別名も使える
- NULL の並び順は DBMS ごとに違う。Postgres は NULLS FIRST/LAST を明示
- ソートはコストがかかる。インデックス設計と合わせて考える
- 日本語の五十音順ソートにはふりがな列を別途用意する
- 大量データを ORDER BY するときは LIMIT と併用し、必要な件数だけ取り出すと負荷を抑えられる
次のレッスン
次は LIMITで件数制限 です。SQLのLIMIT句を使って、取得するデータ件数を制限する方法を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- ORDER BY の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. ORDER BY とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
テーブル構造
schema.sql
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
category VARCHAR(30) NOT NULL,
price INT NOT NULL,
stock INT NOT NULL
);
INSERT INTO products (id, name, category, price, stock) VALUES
(1, 'コーヒー豆 ブレンド', '食品', 1200, 50),
(2, 'マグカップ 白', '雑貨', 800, 120),
(3, 'ノート A5', '文具', 350, 200),
(4, 'ボールペン 黒', '文具', 150, 500),
(5, 'ドリッパー V60', '雑貨', 2500, 30),
(6, 'コーヒー豆 シングル', '食品', 1800, 25),
(7, 'ふせん 100枚', '文具', 220, 300),
(8, 'ケトル 1.0L', '雑貨', 4500, 15);期待される出力
| id | name | category | price |
|---|---|---|---|
| 3 | ノート A5 | 文具 | 350 |
| 7 | ふせん 100枚 | 文具 | 220 |
| 4 | ボールペン 黒 | 文具 | 150 |
| 8 | ケトル 1.0L | 雑貨 | 4500 |
| 5 | ドリッパー V60 | 雑貨 | 2500 |
| 2 | マグカップ 白 | 雑貨 | 800 |
| 6 | コーヒー豆 シングル | 食品 | 1800 |
| 1 | コーヒー豆 ブレンド | 食品 | 1200 |