Немного усложним запрос про получение количества товаров в категории из предыдущего задания. Исходный запрос:
SELECT category_id,
count(*) as count_products
FROM product
GROUP BY category_id
Идентификаторы малоинформативны и обычно никому не интересны. Давай в дополнение к идентификатору категории добавим еще название. Для этого нужно присоединить таблицу category:
SELECT p.category_id,
c.name,
count(*) AS count_products
FROM product p
JOIN category c
ON c.category_id = p.category_id
GROUP BY p.category_id
ORDER BY p.category_id
Но в результате получим ошибку:
column "c.name" must appear in the GROUP BY clause or be used in an aggregate function
Ошибка возникла потому, что мы в списке выборки указали c.name, но не добавили это поле в GROUP BY. Исправим это:
SELECT p.category_id,
c.name,
count(*) AS count_products
FROM product p
JOIN category c
ON c.category_id = p.category_id
GROUP BY p.category_id, c.name
ORDER BY p.category_id
| category_id | name | count_products |
|---|---|---|
| 3 | Бытовая техника | 2 |
| 5 | Фотоаппараты | 2 |
| 6 | Игровые консоли | 3 |
| 7 | Аудиотехника | 1 |
P.S. Ошибка бы не возникла, если вместо
GROUP BY p.category_id
написать
GROUP BY c.category_id
СУБД PostgreSQL поймет, что c.category_id является первичным ключом в таблице category и по c.category_id можно однозначно определить c.name. Но так лучше не делать, т.к. в других версиях PostgreSQL это может не работать, как это не работает в других СУБД, например в Oracle.
Если выражение используется в списке выборки, то его нужно включить в GROUP BY, либо вызвать агрегатную функцию от этого выражения. Обратное не требуется: использованное в GROUP BY выражение не обязательно должно присутствовать в списке выборки. В нашем запросе category_id можно было не включать в список выборки SELECT, но в GROUP BY его стоит оставить (название категории может повторяться в рамках таблицы category, и если в GROUP BY оставить только c.name, то останется только одна строка с таким названием, а количество товаров будет равно количеству товаров во всех категориях с таким названием).