Корректность запросов

Гранулярность результата и уникальность ключа

Содержание курса

Заказы и клиенты: почему в отчёте разное число строк

Подготовим две таблицы в SQLite: справочник клиентов и список их покупок.

CREATE TABLE clients(
    client_id INTEGER PRIMARY KEY,
    client_name TEXT
);

CREATE TABLE orders(
    order_id INTEGER PRIMARY KEY,
    client_id INTEGER,
    order_date TEXT,
    total INTEGER
);

INSERT INTO clients VALUES
    (1, 'Анна'),
    (2, 'Борис'),
    (3, 'Вера');

INSERT INTO orders VALUES
    (101, 1, '2024-01-10', 1000),
    (102, 1, '2024-01-15', 2000),
    (103, 2, '2024-01-12', 1500);

В таблице clients лежат три клиента. В таблице orders лежат три заказа: два принадлежат Анне, один — Борису. У Веры заказов нет.

Соединим обе таблицы обычным INNER JOIN:

SELECT
    c.client_id,
    c.client_name,
    o.order_id,
    o.order_date,
    o.total
FROM clients c
JOIN orders o ON o.client_id = c.client_id
ORDER BY o.order_id;

Запрос возвращает 3 строки:

client_id client_name order_id order_date total
1 Анна 101 2024-01-10 1000
1 Анна 102 2024-01-15 2000
2 Борис 103 2024-01-12 1500

Здесь каждая строка показывает один оформленный заказ. Так как у Анны два заказа, строка с её именем выведена дважды.

Теперь сгруппируем заказы по клиентам и посчитаем сумму покупок:

SELECT
    c.client_id,
    c.client_name,
    SUM(o.total) AS total_spent
FROM clients c
JOIN orders o ON o.client_id = c.client_id
GROUP BY c.client_id, c.client_name
ORDER BY c.client_id;

Результат изменился: теперь в нём 2 строки:

client_id client_name total_spent
1 Анна 3000
2 Борис 1500

Гранулярность — это то, какой именно объект описывает одна строка результата. В первом запросе гранулярность — «один заказ». Во втором запросе гранулярность — «один клиент с покупками». Из-за этого Анна попала во второй отчёт ровно один раз с суммой двух заказов 1000 + 2000 = 3000. Веры в обоих отчётах нет: INNER JOIN оставил только тех клиентов, у которых есть совпадающие строки в таблице orders.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.