Spec-Zone .ru
спецификации, руководства, описания, API

12.17.3. MySQL Extensions к GROUP BY

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

SELECT o.custid, c.name, MAX(o.payment)  FROM orders AS o, customers AS c  WHERE o.custid = c.custid  GROUP BY o.custid;

Для запроса, чтобы быть законным, name столбец должен быть опущен из списка выборки или назван в GROUP BY пункт.

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

Подобное расширение MySQL применяется к HAVING пункт. В стандартном SQL, запрос, который включает a GROUP BY пункт не может отнестись к неагрегированным столбцам в HAVING пункт, которые не называют в GROUP BY пункт. Расширение MySQL разрешает ссылкам на такие столбцы упрощать вычисления. Это расширение предполагает, что у несгруппированных столбцов будут те же самые мудрые группой значения. Иначе, результат неопределенен.

Отключить MySQL GROUP BY расширение, включите ONLY_FULL_GROUP_BY Режим SQL. Это включает стандартному поведению SQL: Столбцы, не названные в GROUP BY пункт не может использоваться в списке выборки или HAVING пункт если не включено в агрегатную функцию.

ONLY_FULL_GROUP_BY также влияет на использование псевдонимов в HAVING пункты. Например, следующие возвраты запроса name значения, которые происходят только однажды в таблице orders:

SELECT name, COUNT(name) FROM orders  GROUP BY name  HAVING COUNT(name) = 1;

MySQL расширяет это поведение, чтобы разрешить использование псевдонима в HAVING пункт для агрегированного столбца:

SELECT name, COUNT(name) AS c FROM orders  GROUP BY name  HAVING c = 1;

Включение ONLY_FULL_GROUP_BY отключает это расширение MySQL и a non-grouping field 'c' is used in HAVING clause ошибка происходит потому что столбец c в HAVING пункт не включается в агрегатную функцию (вместо этого, это - агрегатная функция).

Расширение списка выборки также применяется к ORDER BY. Таким образом, можно обратиться к неагрегированным столбцам в ORDER BY пункт, которые не появляются в GROUP BY пункт. (Однако, как упомянуто ранее, ORDER BY не влияет, какие значения выбираются из неагрегированных столбцов; это только сортирует их после того, как они были выбраны.) Это расширение не применяется если ONLY_FULL_GROUP_BY Режим SQL включается.

В некоторых случаях можно использовать MIN() и MAX() получить определенное значение столбца, даже если это не уникально. Если sort столбец содержит целые числа, не больше чем 6 цифр, следующий запрос дает значение column от строки, содержащей самое маленькое sort значение:

SUBSTR(MIN(CONCAT(LPAD(sort,6,'0'),column)),7)

См. Раздел 3.6.4, "Строки, Содержащие Мудрый группой Максимум Определенного Столбца".

Если Вы пытаетесь следовать за стандартным SQL, невозможно использовать выражения в GROUP BY пункты. Как обходное решение, используйте псевдоним для выражения:

SELECT id, FLOOR(value/100) AS val  FROM tbl_name  GROUP BY id, val;

MySQL разрешает выражения в GROUP BY пункты, таким образом, псевдоним является ненужным:

SELECT id, FLOOR(value/100)  FROM tbl_name  GROUP BY id, FLOOR(value/100);