SQL — Разница между .* и * в запросе агрегатной функции

#sql #database #backend

Вопрос:

 SELECT reviews.*, COUNT(comments.review_id)
AS comment_count
FROM reviews
LEFT JOIN comments ON comments.review_id = reviews.review_id
GROUP BY reviews.review_id
ORDER BY reviews.review_id ASC;
 

Когда я запускаю этот код, я получаю именно то, что мне нужно, из моего SQL-запроса, однако, если я выполню следующее

 SELECT *, COUNT(comments.review_id)
AS comment_count
FROM reviews
LEFT JOIN comments ON comments.review_id = reviews.review_id
GROUP BY reviews.review_id
ORDER BY reviews.review_id ASC;
 

затем я получаю сообщение об ошибке «столбец должен отображаться в предложении GROUP BY или использоваться в агрегатной функции

Просто интересно, в чем разница и почему поведение отличается.

Спасибо

Комментарии:

1. * обозначает все столбцы из всех таблиц в запросе. Ваша comments таблица содержит два или более столбцов, и по крайней мере один из них не агрегирован и не сгруппирован по.

2. Какие СУБД вы используете?

Ответ №1:

В первом примере столбцы берутся только из reviews таблицы. Хотя базы данных не позволяют использовать SELECT * with GROUP BY , это разрешено стандартным SQL, если предположить, что review_id это первичный ключ.

Проблема в том, что вы включаете столбцы в SELECT , которые не включены в GROUP BY . Это разрешено только-в определенных базах данных-при очень особых обстоятельствах, когда столбцы в GROUP BY объявлены для уникальной идентификации каждой строки (что primary key делает a).

Во втором примере есть столбцы, comments которые не соответствуют этому условию. Следовательно, это недопустимо.

Комментарии:

1. Спасибо, что так быстро перезвонил мне, Гордон

2. Просто примечание — стандартный SQL ANSI/ISO не позволяет объединять один * файл с чем-либо вообще в списке выбора.

Ответ №2:

В части выбора запроса с группой по вы можете выбрать только те столбцы, которые вы использовали в группе по.

Поскольку вы сгруппировали по reviews.review_id, вы можете получить выходные данные для первого случая. Во втором запросе вы пытаетесь получить все записи, а это невозможно с помощью group by.

Вы можете использовать функцию окна, если вам нужно выбрать столбцы, которых нет в предложении group by. Надеюсь, в этом есть смысл.

https://www.windowfunctions.com/

Комментарии:

1. Ваше первое утверждение неверно. Первый запрос операции работает.

2. Я думаю, что это сработало, потому что, вероятно, есть только одна колонка с именем, начинающимся с отзывов (review_id).