Подзапросы в роли столбцов
Подзапрос может быть и столбцом результата. Сколько отзывов у каждой игры?
SELECT g.title,
(SELECT COUNT(*) FROM reviews AS r WHERE r.game_id = g.id) AS review_count
FROM games AS g
ORDER BY review_count DESC, g.title;| title | review_count |
|---|---|
| Dragon Forge | 4 |
| Cube Logic | 2 |
| Knight's Oath | 2 |
| Moon Farm | 2 |
| … | … |
Подзапрос коррелированный, как и те, что с EXISTS: он обращается к g.id — игре из внешней строки. Для каждой игры база данных считает отзывы с идентификатором этой игры, и число попадает в столбец review_count. Castle Siege и остальные игры без отзывов получают 0, потому что COUNT(*) по пустому набору строк равен 0.
Подзапрос в SELECT должен давать одно значение для каждой строки: он должен возвращать один столбец и находить не больше одной строки (из нескольких SQLite молча взял бы первую), поэтому обычно это агрегатная функция. Если же он не находит ни одной строки, значение равно NULL. И дайте столбцу псевдоним, иначе его именем станет весь текст подзапроса.
Вы знаете и другой способ подсчёта: LEFT JOIN с GROUP BY и COUNT(r.stars) из урока о соединениях. Оба дают один и тот же результат. Подзапросы удобны, когда нужно несколько чисел из разных таблиц: каждый подзапрос считает сам по себе, поэтому строки не умножаются, как при одновременном соединении reviews и order_items с играми (одна из ловушек соединений из урока о них).
Типичная ошибка: забыть условие, которое связывает подзапрос со строкой. (SELECT COUNT(*) FROM reviews) считает все отзывы в таблице, так что у каждой игры было бы 25.
Задание
- 1
Покажите для каждого клиента имя и дату его последнего заказа как
last_order. Используйте подзапрос вSELECT, который находит самое позднее значениеordered_atсреди заказов клиента. Отсортируйте по имени:name last_order Ava Green 2025-04-15 Emma Clark 2025-11-14 Grace Hall 2025-09-27 Henry Scott NULL … … - 2
Henry Scott и Max Baker ничего не заказывали, поэтому их
last_orderравенNULL. Покажите вместо него текстnever: поместите весь подзапрос вCOALESCE(). Тогда результат начинается так:name last_order Ava Green 2025-04-15 Emma Clark 2025-11-14 Grace Hall 2025-09-27 Henry Scott never … … - 3
Ниже покажите для каждой игры её название, число экземпляров, которые заказали клиенты, как
copies(суммаquantityвorder_items), и среднюю оценку, округлённую до одного знака после запятой, какrating. Понадобятся два подзапроса. Отсортируйте по названию:title copies rating Bakery Story 3 4.0 Castle Siege 1 NULL Cube Logic 3 4.0 Dragon Forge 4 4.3 … … …