データベースからデータを取得する際、結果を特定の順序で表示したいと思うことはよくあります。特に、売上の高い順、日付の新しい順、価格の高い順など、「大きい値から小さい値」の順序で表示したい場面は多いでしょう。
この記事では、SQLのORDER BY句を使って降順(DESC)に並べ替える方法を、基本から応用まで初心者にもわかりやすく解説します。
ORDER BYの基本概念を理解しよう

ORDER BY句とは
ORDER BY句は、SQLのSELECT文で取得したデータを指定した順序で並べ替えるための機能です。
ORDER BYの基本的な役割:
- データを見やすい順序で表示
- 分析や報告書作成での活用
- アプリケーションでの表示順序制御
- データの傾向把握を支援
並べ替えの種類:
- 昇順(ASC):小さい値から大きい値へ(1, 2, 3…)
- 降順(DESC):大きい値から小さい値へ(3, 2, 1…)
降順(DESC)とは
降順の意味:
- DESCending(下降)の略
- 大きい値から小さい値へ並ぶ
- 新しい日付から古い日付へ
- 高い金額から低い金額へ
降順が使われる場面:
- 売上ランキング(高い順)
- 最新ニュース(新しい順)
- 人気商品リスト(人気順)
- 高額商品一覧(価格順)
基本的なORDER BY DESC構文

単一カラムでの降順並べ替え
基本構文:
SELECT column1, column2, column3
FROM table_name
ORDER BY column1 DESC;
構文の詳細説明:
SELECT
:取得するカラムを指定FROM
:データを取得するテーブルを指定ORDER BY
:並べ替えを行うキーワードcolumn1
:並べ替えの基準となるカラムDESC
:降順を指定するキーワード
具体的な使用例
社員の給与を高い順に表示:
SELECT employee_id, name, salary
FROM employees
ORDER BY salary DESC;
商品を価格の高い順に表示:
SELECT product_id, product_name, price
FROM products
ORDER BY price DESC;
注文を日付の新しい順に表示:
SELECT order_id, customer_name, order_date
FROM orders
ORDER BY order_date DESC;
ASC(昇順)との比較
昇順(ASC)の例:
-- 給与の安い順(昇順)
SELECT name, salary
FROM employees
ORDER BY salary ASC;
-- または(ASCは省略可能)
SELECT name, salary
FROM employees
ORDER BY salary;
降順(DESC)の例:
-- 給与の高い順(降順)
SELECT name, salary
FROM employees
ORDER BY salary DESC;
複数カラムでの並べ替え
複数条件での並べ替え基本
複数のカラムを使って、より詳細な並べ替えを行うことができます。
基本構文:
SELECT column1, column2, column3
FROM table_name
ORDER BY column1 DESC, column2 ASC, column3 DESC;
並べ替えの優先順位:
- 最初に指定したカラムで並べ替え
- 同じ値の場合、次のカラムで並べ替え
- さらに同じ値の場合、その次のカラムで並べ替え
実用的な複数カラム並べ替え例
部署別の給与ランキング:
SELECT department, name, salary
FROM employees
ORDER BY department ASC, salary DESC;
この例の結果:
- まず部署名でアルファベット順(昇順)
- 同じ部署内では給与の高い順(降順)
商品カテゴリ別の人気順:
SELECT category, product_name, sales_count, price
FROM products
ORDER BY category ASC, sales_count DESC, price DESC;
並べ替えの流れ:
- カテゴリーで昇順並べ替え
- 同じカテゴリー内では販売数の多い順
- 販売数も同じ場合は価格の高い順
文字列と数値の混在
異なるデータ型での並べ替え:
SELECT customer_name, registration_date, total_purchases
FROM customers
ORDER BY registration_date DESC, customer_name ASC, total_purchases DESC;
並べ替えの詳細:
- 登録日:新しい順(日付型)
- 顧客名:アルファベット順(文字列型)
- 購入総額:高い順(数値型)
データ型別の降順並べ替え

数値型データの降順
整数・小数点数の並べ替え:
-- 価格順(高い順)
SELECT product_name, price
FROM products
WHERE price IS NOT NULL
ORDER BY price DESC;
-- 売上順(多い順)
SELECT sales_person, total_sales
FROM sales_summary
ORDER BY total_sales DESC;
範囲を指定した数値並べ替え:
-- 高額商品(10万円以上)の価格順
SELECT product_name, price
FROM products
WHERE price >= 100000
ORDER BY price DESC;
日付・時刻型データの降順
日付の新しい順:
-- 最新の注文から表示
SELECT order_id, customer_name, order_date
FROM orders
ORDER BY order_date DESC;
-- 今月の売上(新しい順)
SELECT sale_date, amount
FROM sales
WHERE sale_date >= DATE_FORMAT(NOW(), '%Y-%m-01')
ORDER BY sale_date DESC;
時刻を含む並べ替え:
-- 今日の取引(最新順)
SELECT transaction_id, amount, transaction_datetime
FROM transactions
WHERE DATE(transaction_datetime) = CURDATE()
ORDER BY transaction_datetime DESC;
文字列型データの降順
アルファベット逆順:
-- 顧客名をZ→A順で表示
SELECT customer_name, email
FROM customers
ORDER BY customer_name DESC;
日本語の並べ替え:
-- 商品名をあいうえお逆順で表示
SELECT product_name, category
FROM products
ORDER BY product_name DESC COLLATE utf8mb4_unicode_ci;
高度な降順並べ替えテクニック

CASE文を使った条件付き並べ替え
優先度に基づく並べ替え:
SELECT order_id, status, priority, order_date
FROM orders
ORDER BY
CASE status
WHEN '緊急' THEN 1
WHEN '高' THEN 2
WHEN '中' THEN 3
WHEN '低' THEN 4
END ASC,
order_date DESC;
カスタム順序での並べ替え:
SELECT employee_name, department, position
FROM employees
ORDER BY
CASE department
WHEN '取締役' THEN 1
WHEN '部長' THEN 2
WHEN '課長' THEN 3
WHEN '主任' THEN 4
ELSE 5
END ASC,
salary DESC;
関数を使った並べ替え
計算結果での並べ替え:
-- 利益率の高い順
SELECT product_name, selling_price, cost_price,
(selling_price - cost_price) / cost_price * 100 AS profit_rate
FROM products
ORDER BY (selling_price - cost_price) / cost_price DESC;
文字列の長さでの並べ替え:
-- 商品名の長い順
SELECT product_name, LENGTH(product_name) AS name_length
FROM products
ORDER BY LENGTH(product_name) DESC;
サブクエリとの組み合わせ
集計結果での並べ替え:
-- 売上の多い顧客順
SELECT c.customer_name,
(SELECT SUM(amount)
FROM orders o
WHERE o.customer_id = c.customer_id) AS total_sales
FROM customers c
ORDER BY total_sales DESC;
ランキング機能の実装:
-- 部署別売上ランキング
SELECT department,
employee_name,
sales_amount,
RANK() OVER (PARTITION BY department ORDER BY sales_amount DESC) AS ranking
FROM employee_sales
ORDER BY department ASC, ranking ASC;
NULL値の取り扱い
NULL値を含む降順並べ替え
MySQL でのNULL値の扱い:
-- NULLを最後に表示(MySQL)
SELECT name, salary
FROM employees
ORDER BY salary DESC;
-- NULLを最初に表示したい場合
SELECT name, salary
FROM employees
ORDER BY salary IS NULL DESC, salary DESC;
PostgreSQL でのNULL値制御:
-- NULLを最後に表示
SELECT name, salary
FROM employees
ORDER BY salary DESC NULLS LAST;
-- NULLを最初に表示
SELECT name, salary
FROM employees
ORDER BY salary DESC NULLS FIRST;
NULL値の代替処理
COALESCE関数を使った処理:
-- NULLを0として扱って並べ替え
SELECT name, COALESCE(salary, 0) AS display_salary
FROM employees
ORDER BY COALESCE(salary, 0) DESC;
ISNULL関数(SQL Server)での処理:
-- SQL Server でのNULL処理
SELECT name, ISNULL(salary, 0) AS display_salary
FROM employees
ORDER BY ISNULL(salary, 0) DESC;
パフォーマンス最適化

インデックスの活用
効果的なインデックス設計:
-- 降順並べ替え用のインデックス
CREATE INDEX idx_salary_desc ON employees (salary DESC);
CREATE INDEX idx_order_date_desc ON orders (order_date DESC);
-- 複合インデックス
CREATE INDEX idx_dept_salary ON employees (department ASC, salary DESC);
インデックスを活用したクエリ:
-- インデックスが効果的に使用される例
SELECT name, salary
FROM employees
WHERE department = '営業部'
ORDER BY salary DESC;
LIMIT句との組み合わせ
上位N件の取得:
-- 売上上位10名
SELECT employee_name, total_sales
FROM sales_summary
ORDER BY total_sales DESC
LIMIT 10;
-- 最新の注文5件
SELECT order_id, customer_name, order_date
FROM orders
ORDER BY order_date DESC
LIMIT 5;
実行計画の確認
EXPLAIN文での性能確認:
-- MySQL での実行計画確認
EXPLAIN SELECT name, salary
FROM employees
ORDER BY salary DESC;
-- PostgreSQL での詳細実行計画
EXPLAIN ANALYZE SELECT name, salary
FROM employees
ORDER BY salary DESC;
実践的な使用例
ビジネスレポートでの活用
月次売上レポート:
SELECT
DATE_FORMAT(sale_date, '%Y-%m') AS month,
SUM(amount) AS monthly_sales
FROM sales
WHERE sale_date >= DATE_SUB(NOW(), INTERVAL 12 MONTH)
GROUP BY DATE_FORMAT(sale_date, '%Y-%m')
ORDER BY month DESC;
顧客別購入履歴:
SELECT
c.customer_name,
o.order_date,
SUM(od.quantity * od.unit_price) AS order_total
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_details od ON o.order_id = od.order_id
GROUP BY c.customer_id, c.customer_name, o.order_id, o.order_date
ORDER BY c.customer_name ASC, o.order_date DESC;
ダッシュボード用クエリ
リアルタイム売上ランキング:
-- 今日の売上ランキング
SELECT
p.product_name,
SUM(od.quantity) AS units_sold,
SUM(od.quantity * od.unit_price) AS revenue
FROM products p
JOIN order_details od ON p.product_id = od.product_id
JOIN orders o ON od.order_id = o.order_id
WHERE DATE(o.order_date) = CURDATE()
GROUP BY p.product_id, p.product_name
ORDER BY revenue DESC, units_sold DESC;
アクティブユーザーランキング:
-- 最近30日間のアクティブユーザー
SELECT
u.username,
COUNT(l.login_id) AS login_count,
MAX(l.login_datetime) AS last_login
FROM users u
JOIN login_logs l ON u.user_id = l.user_id
WHERE l.login_datetime >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY u.user_id, u.username
ORDER BY login_count DESC, last_login DESC;
よくある間違いと対処法

間違いやすいポイント
間違い1:ORDER BYの位置
-- 間違った例
SELECT name, salary
ORDER BY salary DESC
FROM employees;
-- 正しい例
SELECT name, salary
FROM employees
ORDER BY salary DESC;
間違い2:グループ化との併用
-- 間違った例
SELECT department, AVG(salary)
FROM employees
ORDER BY salary DESC
GROUP BY department;
-- 正しい例
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
ORDER BY avg_salary DESC;
間違い3:エイリアスの使用
-- 問題のある例
SELECT name, salary * 12 AS annual_salary
FROM employees
ORDER BY salary * 12 DESC;
-- 効率的な例
SELECT name, salary * 12 AS annual_salary
FROM employees
ORDER BY annual_salary DESC;
デバッグのコツ
段階的な確認方法:
-- 1. 基本的なSELECTを確認
SELECT name, salary FROM employees;
-- 2. WHERE条件を追加
SELECT name, salary FROM employees WHERE department = '営業部';
-- 3. ORDER BYを追加
SELECT name, salary FROM employees
WHERE department = '営業部'
ORDER BY salary DESC;
まとめ
SQLのORDER BYで降順に並べ替える方法について、重要なポイントをまとめます:
基本的な構文:
- 単一カラム:
ORDER BY column_name DESC
- 複数カラム:
ORDER BY col1 DESC, col2 ASC
- NULL値制御:データベースによる差異に注意
- 関数との組み合わせ:計算結果やCASE文での並べ替え
実践的なポイント:
- 適切なインデックス設計
- LIMIT句との効果的な組み合わせ
- NULL値の適切な処理
- パフォーマンスを考慮したクエリ作成
よくある使用例:
- 売上・人気・評価ランキング
- 最新情報の表示
- 高額・高価格商品の一覧
- 時系列データの新しい順表示
最適化のコツ:
- 並べ替え対象カラムにインデックス作成
- 必要な件数のみLIMITで制限
- 実行計画の定期的な確認
- 適切なデータ型の使用
コメント