平均より人気の本
中段 / 目安 30分
「人気」を上位5冊のような固定の数ではなく、平均との比較で定義し直します。館の規模が変わっても意味が変わらない指標にしたいからです。
比べる相手の平均は、貸出履歴のある本だけで計算します。一度も借りられていない本を分母に入れると、平均が下がって基準が甘くなるためです。
完成条件
貸出履歴のある本について、1冊あたりの平均貸出回数を求め、それを上回る本を取り出してください。
- 出す列は
titleとloan_countの2つ - 並びは
loan_countの降順。同数ならbooks.idの昇順
中間結果を1つの数と比べる
店舗別の売上回数から平均を求める例で流れを確認します。sales が次の5行なら、店舗1の売上は2回、店舗2は3回です。
| shop_id | sale_id |
|---|---|
| 1 | 101 |
| 1 | 102 |
| 2 | 103 |
| 2 | 104 |
| 2 | 105 |
WITH 名前 AS (...) は、かっこの中の結果に名前を付け、そのSQLの中でテーブルのように使う書き方です。
SQL クエリ
WITH per_shop AS (
SELECT shop_id, count(*) AS sale_count
FROM sales
GROUP BY shop_id
)
SELECT avg(sale_count) AS average_count
FROM per_shop;per_shop の中間結果は次の2行です。avg(sale_count) は、この2行の件数から平均 (2 + 3) / 2 = 2.5 を求めます。売上の1行ずつではなく、店舗ごとに数えた結果を平均する点が大切です。
| shop_id | sale_count |
|---|---|
| 1 | 2 |
| 2 | 3 |
同じ WITH に続く最後の SELECT を次にすると、平均より多い店舗2だけを取り出せます。
SQL クエリ
SELECT shop_id, sale_count
FROM per_shop
WHERE sale_count > (
SELECT avg(sale_count) FROM per_shop
)
ORDER BY sale_count DESC, shop_id ASC;かっこの中の SELECT は副問い合わせです。ここでは平均という1つの数を返すので、WHERE の比較に使えます。平均と等しい行は > では残りません。
ひな形の結合も確認しておきます。AS は短い別名を付け、JOIN ... ON は条件に合う行同士をつなぎます。
SQL クエリ
SELECT s.shop_name, p.sale_count
FROM per_shop AS p
JOIN shops AS s ON s.shop_id = p.shop_id;この例は同じ per_shop の後ろに続けるもので、店舗の番号を手掛かりに店舗名を付けます。演習でも同じ方法で本の題名を付けてあります。
進め方
本ごとの貸出回数を作る per_book と、本の題名を結び付ける部分はひな形にあります。その後ろに、平均との比較を3行、並べ替えを1行足してください。手が止まったらヒントを開けます。ヒントは3段階で、①方針、②使う構文、③部分解の順に出ます。1つも開けずに通せたら、その問題は自分のものです。
開かずに10分粘って進まないなら、①だけ開けてください。粘る時間そのものには価値がありません。価値があるのは、自分で書いた行が動いた瞬間です。
平均そのものは1つの数です。まとめた結果を、その数と比べます。
テーブル構造
CREATE TABLE members (
id integer PRIMARY KEY,
name text NOT NULL,
joined_on date NOT NULL,
plan text NOT NULL
);
CREATE TABLE books (
id integer PRIMARY KEY,
title text NOT NULL,
author text NOT NULL,
genre text NOT NULL,
published_year integer NOT NULL,
price integer NOT NULL
);
CREATE TABLE loans (
id integer PRIMARY KEY,
book_id integer NOT NULL REFERENCES books (id),
member_id integer NOT NULL REFERENCES members (id),
borrowed_on date NOT NULL,
returned_on date
);
INSERT INTO members VALUES
(1, '田中あかり', DATE '2024-04-01', '一般'),
(2, '佐藤けんじ', DATE '2024-06-15', '一般'),
(3, '鈴木みゆき', DATE '2025-01-20', '学生'),
(4, '高橋なおと', DATE '2025-03-05', '学生'),
(5, '伊藤さくら', DATE '2025-08-11', '一般'),
(6, '渡辺ゆうた', DATE '2026-02-01', '一般');
INSERT INTO books VALUES
(1, '銀河の設計図', '星野りく', 'SF', 2019, 1800),
(2, '沈黙の実験室', '星野りく', 'SF', 2021, 2200),
(3, '夜明けのレシピ', '森田はるか', '料理', 2020, 1500),
(4, '家庭料理の教科書', '森田はるか', '料理', 2018, 2800),
(5, 'やさしい統計入門', '大村しんじ', '技術', 2022, 3200),
(6, 'データベース実践', '大村しんじ', '技術', 2023, 3600),
(7, '山と湖の記録', '川瀬あおい', '生活', 2017, 1600),
(8, '北の島へ', '川瀬あおい', '生活', 2021, 1900),
(9, '猫と暮らす', '林ももこ', '生活', 2024, 1400),
(10, '小さな庭の作り方', '林ももこ', '生活', 2022, 1700),
(11, '消えた手紙', '星野りく', 'SF', 2016, 1300),
(12, '三日月の約束', '藤田けい', 'ミステリ', 2025, 2000),
(13, '軌道の彼方', '星野りく', 'SF', 2024, 2400),
(14, 'ネットワーク入門', '大村しんじ', '技術', 2020, 2900),
(15, '朝のパン作り', '林ももこ', '生活', 2023, 1600);
INSERT INTO loans VALUES
(1, 1, 1, DATE '2026-01-05', DATE '2026-01-19'),
(2, 1, 2, DATE '2026-01-12', DATE '2026-01-26'),
(3, 1, 3, DATE '2026-02-03', DATE '2026-02-17'),
(4, 1, 4, DATE '2026-03-09', DATE '2026-03-23'),
(5, 1, 5, DATE '2026-04-06', DATE '2026-04-20'),
(6, 1, 6, DATE '2026-05-11', NULL),
(7, 9, 1, DATE '2026-01-08', DATE '2026-01-22'),
(8, 9, 2, DATE '2026-02-10', DATE '2026-02-24'),
(9, 9, 3, DATE '2026-03-02', DATE '2026-03-16'),
(10, 9, 4, DATE '2026-04-13', DATE '2026-04-27'),
(11, 9, 5, DATE '2026-05-18', NULL),
(12, 5, 1, DATE '2026-02-16', DATE '2026-03-02'),
(13, 5, 3, DATE '2026-03-23', DATE '2026-04-06'),
(14, 5, 4, DATE '2026-04-20', DATE '2026-05-04'),
(15, 5, 6, DATE '2026-06-01', NULL),
(16, 3, 2, DATE '2026-01-19', DATE '2026-02-02'),
(17, 3, 5, DATE '2026-03-16', DATE '2026-03-30'),
(18, 3, 6, DATE '2026-05-25', NULL),
(19, 12, 1, DATE '2026-04-27', DATE '2026-05-11'),
(20, 12, 3, DATE '2026-06-08', NULL),
(21, 2, 2, DATE '2026-02-23', DATE '2026-03-09'),
(22, 7, 4, DATE '2026-05-04', DATE '2026-05-18'),
(23, 13, 5, DATE '2026-06-15', DATE '2026-06-29');
期待される出力
| title | loan_count |
|---|---|
| 銀河の設計図 | 6 |
| 猫と暮らす | 5 |
| やさしい統計入門 | 4 |
| 夜明けのレシピ | 3 |
ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです