ORDER BY は、クエリが返す行を 1 つ以上の列や式で昇順または降順に並べ替えます。ORDER BY がない場合、データベースは最も速く返せる順序で行を返します。例は PostgreSQL、MySQL、SQLite、SQL Server で動作します。
ORDER BY の使い方
ORDER BY はクエリの最後、WHERE、GROUP BY、HAVING の後に置きます。その後に来るのは LIMIT だけです。並べ替えに使う列を列挙します。DESC を付けない限り、各列は昇順で並べ替えられます:
SELECT columns
FROM table_name
ORDER BY column1 [ASC | DESC], column2 [ASC | DESC];
-- Input: customers
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 1 | Olivia Hart | 2024-03-12
-- 2 | Marcus Lee | 2023-11-05
-- 3 | Zara Ahmed | 2024-01-27
-- 4 | Ben Carter | 2023-08-19
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date;
-- Output:
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 4 | Ben Carter | 2023-08-19
-- 2 | Marcus Lee | 2023-11-05
-- 3 | Zara Ahmed | 2024-01-27
-- 1 | Olivia Hart | 2024-03-12
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date DESC;
-- Output:
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 1 | Olivia Hart | 2024-03-12
-- 3 | Zara Ahmed | 2024-01-27
-- 2 | Marcus Lee | 2023-11-05
-- 4 | Ben Carter | 2023-08-19
知っておくべきルール
-
DESC は直前の列にのみ適用されます。
ORDER BY author, published DESCは著者を A から Z の順に並べ、各著者の本を新しい順に並べます:
-- Input: books
-- title | author | published
-- --------------------+-----------------+----------
-- Emma | Jane Austen | 1815
-- Bleak House | Charles Dickens | 1853
-- Pride and Prejudice | Jane Austen | 1813
-- Hard Times | Charles Dickens | 1854
SELECT title, author, published
FROM books
ORDER BY author, published DESC;
-- Output:
-- title | author | published
-- --------------------+-----------------+----------
-- Hard Times | Charles Dickens | 1854
-- Bleak House | Charles Dickens | 1853
-- Emma | Jane Austen | 1815
-- Pride and Prejudice | Jane Austen | 1813
-
ORDER BY がなければ、順序は保証されません。 行は挿入順に返ってくることが多いですが、テーブルが大きくなったり、インデックスが変わったり、クエリが並列実行されたりすると変わります。
LIMITも同様で、ORDER BY がなければデータベースが最初に読んだ行が返されます。 - 同順位の行は任意の順序で返されます。 ID などの一意な列を最後の並べ替え列として追加すると、毎回同じ順序になります:
-- Input: customers
-- customer_id | name | signup_date
-- ------------+------------+------------
-- 3 | Mara Lind | 2024-01-15
-- 1 | Owen Price | 2024-01-10
-- 4 | Tariq Aziz | 2024-01-15
-- 2 | Lily Shore | 2024-01-15
-- The three 2024-01-15 rows can come back in any order
SELECT * FROM customers ORDER BY signup_date;
-- Output:
-- customer_id | name | signup_date
-- ------------+------------+------------
-- 1 | Owen Price | 2024-01-10
-- 3 | Mara Lind | 2024-01-15
-- 4 | Tariq Aziz | 2024-01-15
-- 2 | Lily Shore | 2024-01-15
-- customer_id breaks the tie
SELECT * FROM customers ORDER BY signup_date, customer_id;
-- Output:
-- customer_id | name | signup_date
-- ------------+------------+------------
-- 1 | Owen Price | 2024-01-10
-- 2 | Lily Shore | 2024-01-15
-- 3 | Mara Lind | 2024-01-15
-- 4 | Tariq Aziz | 2024-01-15
- NULL は先頭に並びます。ただし PostgreSQL では末尾に並びます。 これは昇順の場合で、DESC では逆になります:
-- Input: users
-- name | middle_name
-- -----------+------------
-- John Smith | Robert
-- Ana Lopez | NULL
-- Kim Young | Elise
SELECT name, middle_name
FROM users
ORDER BY middle_name;
-- Output:
-- name | middle_name
-- -----------+------------
-- Ana Lopez | NULL
-- Kim Young | Elise
-- John Smith | Robert
-- (PostgreSQL puts Ana Lopez last instead)
NULL の位置を指定するには、下記の NULLS FIRST と NULLS LAST を参照してください。
別の構文
列のエイリアスや、SELECT リスト内の列の位置で並べ替えることもできます。エイリアスを使えば式を繰り返す必要がありません。位置指定は短く書けますが、誰かが SELECT リストを編集すると気付かないうちに壊れます:
-- Input: employees
-- name | monthly_salary
-- ---------+---------------
-- Ivy Chen | 5200
-- Max Dunn | 7600
-- Pia Roth | 4500
SELECT name, monthly_salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC; -- or ORDER BY 2 DESC
-- Output:
-- name | annual_salary
-- ---------+--------------
-- Max Dunn | 91200
-- Ivy Chen | 62400
-- Pia Roth | 54000
並べ替え列の後に NULLS FIRST や NULLS LAST を付けると、その列の NULL の位置を指定できます:
-- Input: the users table above
SELECT name, middle_name
FROM users
ORDER BY middle_name NULLS LAST;
-- MySQL and SQL Server don't support NULLS LAST. Sort on a CASE first instead:
-- ORDER BY CASE WHEN middle_name IS NULL THEN 1 ELSE 0 END, middle_name
-- Output:
-- name | middle_name
-- -----------+------------
-- Kim Young | Elise
-- John Smith | Robert
-- Ana Lopez | NULL
MySQL には、値を指定した順に並べ替える FIELD() があります。それ以外のデータベースでは、下記のタスクを優先度で並べ替えるのような CASE 式を使います:
-- Input: products
-- product_name | category
-- -------------+------------
-- Cookbook | Books
-- Raincoat | Clothing
-- Tablet | Electronics
-- Scarf | Clothing
-- MySQL
SELECT * FROM products
ORDER BY FIELD(category, 'Electronics', 'Clothing', 'Books');
-- Output:
-- product_name | category
-- -------------+------------
-- Tablet | Electronics
-- Raincoat | Clothing
-- Scarf | Clothing
-- Cookbook | Books
ORDER BY はいつ使うべきか?
行の順序が読み手にとって意味を持つときは、常に ORDER BY を使いましょう。ほとんどの用途は次の 4 つのいずれかに当てはまります。
リストを予測可能な順序で表示する
名前は A から Z、日付は古い順、ID は連番順に。ORDER BY がないと、同じクエリでも実行するたびに行の順序が変わることがあり、結果のページ間で行が重複したり抜けたりすることがあります。
最大値や最新の値を見つける
降順で並べ替えて最大・最新・最も高価な行を先頭にし、LIMIT を加えて上位のみを残します。売れ筋商品、最新の注文、最高スコアなどです。
複数の列で並べ替える
最初の並べ替え列で同順位がある場合、次の列がその中の順序を決めます。部署の次に給与、学年の次にスコア、ステータスの次に日付といった具合です。列ごとに並べ替えの方向を指定できます。
計算値やカスタム順序で並べ替える
ORDER BY には列だけでなく任意の式を指定できます。2 つの列から算出した合計、名前の長さ、あるいは High、Medium、Low のような値をアルファベット順では得られない順序に並べる CASE 式などです。
ORDER BY の実例
顧客リストをページ送りする
ORDER BY と LIMIT、OFFSET を組み合わせると、1 ページずつ結果を返せます。3 人の顧客が同じ日に登録しているため、customer_id で同順位を解消します。これがないと、データベースが同じ顧客を両方のページに表示し、別の顧客を飛ばしてしまう可能性があります:
-- Input: customers
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 1 | Nina Brandt | 2024-02-14
-- 2 | Theo Walsh | 2023-09-30
-- 3 | Iris Novak | 2024-02-14
-- 4 | Felix Moore | 2024-02-14
-- 5 | June Park | 2024-03-22
-- Page 1
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date, customer_id
LIMIT 2 OFFSET 0;
-- Output:
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 2 | Theo Walsh | 2023-09-30
-- 1 | Nina Brandt | 2024-02-14
-- Page 2
SELECT customer_id, name, signup_date
FROM customers
ORDER BY signup_date, customer_id
LIMIT 2 OFFSET 2;
-- SQL Server has no LIMIT: use OFFSET 2 ROWS FETCH NEXT 2 ROWS ONLY
-- Output:
-- customer_id | name | signup_date
-- ------------+-------------+------------
-- 3 | Iris Novak | 2024-02-14
-- 4 | Felix Moore | 2024-02-14
リーダーボードの上位 3 件を表示する
スコアを高い順に並べ替え、最初の 3 件を残します:
-- Input: players
-- username | score
-- ----------+------
-- quokka42 | 1870
-- nightowl | 2310
-- pixelpete | 1525
-- zara_k | 2045
-- bytebard | 1990
SELECT username, score
FROM players
ORDER BY score DESC
LIMIT 3;
-- SQL Server has no LIMIT: write SELECT TOP 3 username, score instead
-- Output:
-- username | score
-- ---------+------
-- nightowl | 2310
-- zara_k | 2045
-- bytebard | 1990
ステータス、金額、日付で注文レポートを作成する
ステータスはアルファベット順に並びます。各ステータス内では金額の大きい注文が先に来て、同じ金額の注文は新しい順に表示されます:
-- Input: orders
-- order_id | status | order_value | order_date
-- ---------+------------+-------------+-----------
-- 1001 | Shipped | 120.00 | 2024-03-02
-- 1002 | Delivered | 75.50 | 2024-02-20
-- 1003 | Shipped | 120.00 | 2024-03-05
-- 1004 | Processing | 42.00 | 2024-03-06
-- 1005 | Delivered | 210.00 | 2024-02-28
SELECT order_id, status, order_value, order_date
FROM orders
ORDER BY status ASC, order_value DESC, order_date DESC;
-- Output:
-- order_id | status | order_value | order_date
-- ---------+------------+-------------+-----------
-- 1005 | Delivered | 210.00 | 2024-02-28
-- 1002 | Delivered | 75.50 | 2024-02-20
-- 1004 | Processing | 42.00 | 2024-03-06
-- 1003 | Shipped | 120.00 | 2024-03-05
-- 1001 | Shipped | 120.00 | 2024-03-02
タスクを優先度で並べ替える
アルファベット順では High、Low、Medium の順になってしまいます。CASE 式で各優先度を並べ替え用の数値に変換します。それ以外の値(ここでは NULL)は 4 になって最後に並び、各優先度内では期日順にタスクが並びます:
-- Input: tasks
-- task_name | priority | due_date
-- ---------------+----------+-----------
-- Update docs | Low | 2024-06-03
-- Fix login bug | High | 2024-06-10
-- Plan offsite | NULL | 2024-05-20
-- Renew SSL cert | High | 2024-06-01
-- Review PR | Medium | 2024-06-04
SELECT task_name, priority, due_date
FROM tasks
ORDER BY
CASE priority
WHEN 'High' THEN 1
WHEN 'Medium' THEN 2
WHEN 'Low' THEN 3
ELSE 4
END,
due_date;
-- Output:
-- task_name | priority | due_date
-- ---------------+----------+-----------
-- Renew SSL cert | High | 2024-06-01
-- Fix login bug | High | 2024-06-10
-- Review PR | Medium | 2024-06-04
-- Update docs | Low | 2024-06-03
-- Plan offsite | NULL | 2024-05-20
ORDER BY についての関連記事
このブログの記事:
- SQL GROUP BY ガイド: 売上上位のカテゴリなど、グループ化した結果の並べ替え
- SQL CASE 文ガイド: カスタムの並べ替え順序のための CASE 式
- PostgreSQL、MySQL、SQLite、SQL Server での行数制限: LIMIT、OFFSET、TOP
- MySQL で上位 N 行を取得する: MySQL での ORDER BY と LIMIT
-
SQL で重複を見つけるガイド:
ROW_NUMBER()内の ORDER BY で、どのコピーをオリジナルとみなすかを決める
公式ドキュメント:
Beekeeper Studioは無料のオープンソースのデータベースGUIです
これまで使った中で最高のSQLクエリ&エディタツールです。データベースの管理に必要なものがすべて揃っています。 - ⭐⭐⭐⭐⭐ Mit
Beekeeper Studioは高速で直感的、そして使いやすいツールです。多数のデータベースに対応し、Windows、Mac、Linuxで快適に動作します。
Beekeeper Studio 利用者の声
「Beekeeper Studio で以前の SQL ワークフローを完全に置き換えました。高速で直感的で、データベース作業がまた楽しくなりました。」
「多くのデータベース GUI を試してきましたが、Beekeeper は機能とシンプルさのバランスが完璧です。とにかくちゃんと動きます。」