CASE式で分類する
CASEは条件によって表示する値を変える式です。上から評価されるため、重なる条件は順番を確認します。
在庫状態を表示SQL
SELECT name, stock,
CASE
WHEN stock = 0 THEN '在庫切れ'
WHEN stock <= 3 THEN '残りわずか'
ELSE '在庫あり'
END AS stock_status
FROM products
ORDER BY id;実行結果OUTPUT
PostgreSQL入門書 5 在庫あり
ノート 12 在庫あり
ボールペン 0 在庫切れ
マグカップ 3 残りわずかGROUP BYとHAVING
COUNT、SUM、AVGでまとまりを集計します。WHEREは集計前、HAVINGは集計後の条件です。
カテゴリ別の在庫SQL
SELECT category,
COUNT(*) AS product_count,
SUM(stock) AS total_stock,
ROUND(AVG(price), 2) AS average_price
FROM products
WHERE category IS NOT NULL
GROUP BY category
HAVING SUM(stock) >= 5
ORDER BY total_stock DESC;実行結果OUTPUT
category product_count total_stock average_price
stationery 2 12 225.00
book 1 5 3280.00INNER JOINで結合する
商品と注文を商品IDで結び付けます。先に注文テーブルを作り、外部キーで存在する商品だけを参照できるようにします。
注文テーブルSQL
CREATE TABLE orders (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
product_id integer NOT NULL REFERENCES products(id),
quantity integer NOT NULL CHECK (quantity > 0),
ordered_at date NOT NULL
);
INSERT INTO orders (product_id, quantity, ordered_at) VALUES
(1, 2, DATE '2026-10-01'),
(2, 3, DATE '2026-10-02');商品名と注文金額SQL
SELECT o.id, p.name, o.quantity,
p.price * o.quantity AS total
FROM orders AS o
INNER JOIN products AS p ON p.id = o.product_id
ORDER BY o.id;実行結果OUTPUT
id name quantity total
1 PostgreSQL入門書 2 6560.00
2 ノート 3 900.00LEFT JOINで未注文も残す
注文がない商品も一覧へ残すなら、左側の商品を必ず返すLEFT JOINを使います。
商品別の注文数SQL
SELECT p.name,
COALESCE(SUM(o.quantity), 0) AS ordered_quantity
FROM products AS p
LEFT JOIN orders AS o ON o.product_id = p.id
GROUP BY p.id, p.name
ORDER BY p.id;実行結果OUTPUT
name ordered_quantity
PostgreSQL入門書 2
ノート 3
ボールペン 0
マグカップ 0右側に一致しない行の集計値はNULLになるため、表示時にCOALESCEで0へ置き換えます。
副問い合わせを使う
平均価格など、別の検索結果を条件へ利用できます。
平均より高い商品SQL
SELECT name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products)
ORDER BY price DESC;実行結果OUTPUT
name price
PostgreSQL入門書 3280.00ウィンドウ関数を使う
ウィンドウ関数は、行を一つにまとめず、周囲の行を参照しながら計算します。カテゴリ内の順位を求める例です。
価格の順位SQL
SELECT name, price,
RANK() OVER (ORDER BY price DESC) AS price_rank
FROM products;実行結果の例OUTPUT
name price price_rank
PostgreSQL入門書 3280.00 1
マグカップ 900.00 2
ノート 300.00 3
ボールペン 150.00 4練習:商品別売上
商品と注文を結合し、商品ごとの売上金額を求めてください。
解答例と実行結果
解答例SQL
SELECT p.name, SUM(p.price * o.quantity) AS sales
FROM products AS p
JOIN orders AS o ON o.product_id = p.id
GROUP BY p.id, p.name
ORDER BY sales DESC;実行結果OUTPUT
name sales
PostgreSQL入門書 6560.00
ノート 900.00