интересно, почему агрегация не работает:я хочу написать sql-запрос для использования агрегации и иметь cluse

#mysql #sql #aggregation #having

Вопрос:

привет, у меня есть 2 таблицы, которые хотят использовать агрегацию и иметь cluse. можете ли вы проверить мой запрос? не работает

 SELECT  registration.Staff_ID,  staff.FirstName,  staff.LastName,  (sum(registration.RegFeeAmntPaid)) AS The_Best_Seller FROM registration,staff WHERE registration.Staff_ID = staff.Staff_ID GROUP BY Staff_ID HAVING MAX(SUM(registration.RegFeeAmntPaid)) = SUM(registration.RegFeeAmntPaid);  

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

1. Вы не можете вложить агрегаты таким образом.

2. Это должно быть два набора: Получите сумму на каждого сотрудника. Затем получите максимальную сумму персонала и сравните. Вы пытаетесь выполнить эти два шага в одном. Для этого была бы полезна оконная функция. Какие СУБД вы используете? (Запросы SQL всегда должны быть помечены СУБД, чтобы не получать ответы, которые вам не подходят.)

3. Я добавил для вас тег MySQL. В стандартном SQL вы можете заменить HAVING предложение на ORDER BY RANK() OVER (ORDER BY SUM(registration.RegFeeAmntPaid) DESC) FETCH FIRST ROW WITH TIES , но MySQL не поддерживает это FETCH предложение. Начиная с MySQL 8 , вы можете использовать RANK OVER и MAX OVER , но для оценки результата вам потребуется подзапрос.

Ответ №1:

Вложенная агрегация MAX(СУММА(регистрация.RegFeeAmntPaid)) проблема в том, что вложенные агрегации не разрешены в SQL: после первой агрегации остается только одно значение. Таким образом, повторное объединение не имеет смысла. (В Oracle в разделе ВЫБОР ГРУППЫ ПО запросу можно использовать вложенную агрегацию для получения одного значения, но это не является стандартным.)

Кроме того, в большинстве систем атрибуты, напечатанные в разделе ВЫБРАТЬ без агрегирования, должны отображаться в разделе СГРУППИРОВАТЬ ПО. (В стандартном SQL и PostgreSQL атрибуты, которые функционально определяются атрибутами GROUP BY, в порядке. Но, например, в Oracle, они должны быть явно упомянуты в разделе GROUP BY, даже если это фактически не изменяет группы.)

Кроме того, в предложении GROUP BY в Staff_ID отсутствует имя переменной table/tupe (неясно, имеете ли вы в виду регистрацию.Staff_ID или staff.Staff_ID. Я знаю, что это не имеет значения, но система SQL не знает.)

Существует несколько решений, позволяющих максимизировать сумму. Один из них заключается в следующем:

 SELECT  registration.Staff_ID,  staff.FirstName,  staff.LastName,  (sum(registration.RegFeeAmntPaid)) AS The_Best_Seller FROM registration,staff WHERE registration.Staff_ID = staff.Staff_ID GROUP BY registration.Staff_ID,  staff.FirstName, staff.LastName HAVING SUM(registration.RegFeeAmntPaid) gt;= ALL  (SELECT SUM(s.RegFeeAmntPaid)  FROM registration s  GROUP BY s.staff_id)  

Другим решением было бы использовать предложение WITH для определения вспомогательной таблицы, содержащей сумму для каждого staff_id. Тогда вы могли бы использовать функцию MAX. Это также возможно без предложения WITH, но тогда нужен подзапрос в разделе FROM (который также дает промежуточную таблицу). Необходимо поместить две совокупности в разные предложения SELECT.

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

1. Это хорошо объяснено. Могут быть лучшие подходы, но это зависит от СУБД. @eli: Что ты используешь?

2. @ThorstenKettner , Спасибо, я использую mysql, phpmyadmin через localhost, xamp