#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