Немного усложним запрос про получение количества товаров в категории из предыдущего задания. Исходный запрос:
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
, то останется только одна строка с таким названием, а количество товаров будет равно количеству товаров во всех категориях с таким названием).