PostgreSQL

検索・集計・結合

必要な行を選び、集計し、複数のテーブルから結果を作ります。

PostgreSQL入門の講座一覧

01

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   残りわずか
02

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.00
03

INNER 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.00
04

LEFT 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へ置き換えます。

05

副問い合わせを使う

平均価格など、別の検索結果を条件へ利用できます。

平均より高い商品SQL
SELECT name, price
FROM products
WHERE price > (SELECT AVG(price) FROM products)
ORDER BY price DESC;
実行結果OUTPUT
name              price
PostgreSQL入門書  3280.00
06

ウィンドウ関数を使う

ウィンドウ関数は、行を一つにまとめず、周囲の行を参照しながら計算します。カテゴリ内の順位を求める例です。

価格の順位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
07

練習:商品別売上

商品と注文を結合し、商品ごとの売上金額を求めてください。

解答例と実行結果
解答例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