Подтвердить что ты не робот

Является ли предложение GROUP BY в SQL избыточным?

Всякий раз, когда мы используем агрегатную функцию в SQL (MIN, MAX, AVG и т.д.), мы должны всегда GROUP BY все неагрегированные столбцы, например:

SELECT storeid, storename, SUM(revenue), COUNT(*)
FROM Sales 
GROUP BY storeid, storename

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

SELECT (2 * (x + y)) / z + 1, MyFunction(x, y), SUM(z)
FROM AnotherTable
GROUP BY (2 * (x + y)) / z + 1, MyFunction(x, y)

Если мы когда-либо изменим инструкцию SELECT, мы должны помнить о том же изменении в нашем предложении GROUP BY.

Итак, предложение GROUP BY является избыточным?

  • Если это действительно так, то почему вообще существует предложение GROUP BY в SQL?
  • Если это не так, то какие дополнительные функции предоставляет GROUP BY?
4b9b3361

Ответ 1

Всякий раз, когда мы используем агрегатную функцию в SQL (MIN, MAX, AVG и т.д.), мы всегда должны GROUP BY всеми неагрегированными столбцами

Это вообще не так. MySQL, к примеру, не требует этого, и стандарт SQL также не говорит об этом.

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

Также не верно в целом. MySQL (и, возможно, другие базы данных тоже) позволяют использовать псевдонимы столбцов в предложении GROUP BY:

SELECT (2 * (x + y)) / z + 1 AS a, MyFunction(x, y) AS b, SUM(z)
FROM AnotherTable
GROUP BY a, b

Если это не так, то какие дополнительные функции предоставляет GROUP BY?

Единственный способ указать, что сгруппировать, - это использовать предложение GROUP BY. Вы не можете вывести его из столбцов, указанных в SELECT. На самом деле вам даже не нужно выбирать все столбцы, упомянутые в GROUP BY:

SELECT MAX(col2)
FROM foo
GROUP BY col1
HAVING COUNT(*) = 2

Ответ 2

Я могу согласиться с тем, что вы говорите, но это не избыточно в случаях all.

Рассмотрим это:

SELECT FirstName 
       + ' (' + REPLACE(Address1, ',', ' ') + ' '
       + REPLACE(Address2, ',', ' ') + ', '
       + UPPER(State) + ' '
       + 'USA)',
       COUNT(*)
FROM Profiles
GROUP BY FirstName, Address1, Address2, State

В этом случае я просто хочу, чтобы число однотипных имен, одинаковых адресов.
Как вы можете видеть, мне не пришлось повторять "сложные" операции SELECT в инструкции GROUP BY.

Я думаю, чтобы позволить "иногда так, иногда так", вам приходится делать повторения большую часть времени.

Ответ 3

Предложение GROUP BY не является избыточным - его функция определяет область действия, на которой работают агрегатные функции. Это ваше убеждение в том, что оптимизатор должен читать из предложения SELECT, чтобы узнать, какова область действия группировки, но доступ к псевдонимам столбцов доступен в предложении ORDER BY как можно раньше (за исключением MySQL, где GROUP BY и HAVING - вспомогательные псевдонимы столбцов). В настоящее время нет средств для поддержки ваших ожиданий. Стандарты ANSI хороши, но на самом деле стандарты ANSI не реализованы в целом поставщиками. Он поддерживает поиск и поддержку, как то, как PostgreSQL 8.4+ поддерживает больше аналитических функций, чем Oracle (конечно, больше, чем SQL Server).

Поддержка MySQL и SQLite, исключающая столбцы из GROUP BY, но эти значения столбцов для документации произвольны - это значение не может быть гарантировано возвращено последовательно. И объем группировки также различен, что может существенно повлиять на возвращаемый результат. Тогда возникает проблема полагаться на специфический синтаксис поставщика, когда требуется перенос в другие базы данных, поскольку DB2, Oracle, SQL Server и PostgreSQL не поддерживают функциональность.

Но с появлением аналитической/оконной/ранговой функциональности вы можете получить совокупную функциональность без GROUP BY. IE:

SELECT t.id,
       COUNT(t.column) OVER(PARTITION BY t.id) AS num,
       SUM(t.column) OVER(PARTITION BY t.id) AS sum
  FROM YOUR_TABLE t

Это более подробный и подверженный ошибкам, хотя из-за того, что вы не можете определить PARTITION BY/ORDER BY, который применяется ко всем аналитическим функциям в запросе. В настоящее время... Но Analytics не вытеснит агрегаты в ближайшее время - поддержка началась в Oracle 9i, SQL Server 2005+ и PostgreSQL 8.4+. Я знаю, что DB2 поддерживает аналитику, но я не знаю подробностей, кроме этого.

Ответ 4

  • Главное здесь (2 * (x + y)) / z + 1, MyFunction(x, y) после GROUP BY, нужно, чтобы сумма знала, как сводить.
  • Но (2 * (x + y)) / z + 1, MyFunction(x, y) после SELECT необязательно. Как вы хотите, чтобы результат стал, а не влиял на sum()
    Как и сказал BeemerGuy, 2. не всегда одинаково с 1.