Articles

MySQL : MySQL 5.6 Manual de Referência :: 12.19.3 MySQL Manipulação de GRUPO

12.19.3 MySQL Manipulação de GRUPO

No padrão SQL, uma consulta que inclui uma GROUP BY cláusula não pode se referir a nonaggregated colunas na lista select que não são nomeadas GROUP BY cláusula. Por exemplo, esta consulta é ilegal em SQL padrão porque a coluna não-agregada name na lista selecionada não aparece na lista 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;

para que a consulta seja legal, o name coluna deve ser omitido da lista de seleção ou com o nome de GROUP BY cláusula.

MySQL estende o uso padrão de SQL de GROUP BYde modo que a lista selecionada possa se referir a colunas não agregadas não nomeadas na cláusulaGROUP BY. Isto significa que a consulta anterior é legal no MySQL. Você pode usar este recurso para obter um melhor desempenho, evitando a ordenação e agrupamento desnecessários de colunas. No entanto, isto é útil principalmente quando todos os valores em cada coluna não agregada não nomeados no GROUP BY são os mesmos para cada grupo. O servidor é livre para escolher qualquer valor de cada grupo, então, a menos que eles sejam os mesmos, os valores escolhidos são não determinísticos. Além disso, a seleção de valores de cada grupo não pode ser influenciada pela adição de uma cláusula ORDER BY. A ordenação do conjunto de resultados ocorre após os valores terem sido escolhidos, e ORDER BY não afeta os valores dentro de cada grupo que o servidor escolhe.

uma extensão MySQL semelhante aplica-se à cláusula HAVING. In standard SQL, a query cannot refer to nonaggregated columns in the HAVING clause that are not named in the GROUP BY clause. Para simplificar os cálculos, uma extensão MySQL permite referências a tais colunas. Esta extensão assume que as colunas nongrouped têm os mesmos valores em grupo. Caso contrário, o resultado é não determinístico.

para desactivar a extensão MySQLGROUP BY e activar o comportamento SQL padrão, active o ONLY_FULL_GROUP_BY modo SQL. Neste caso, as colunas não mencionadas na cláusula GROUP BY não podem ser utilizadas na lista seleta ouHAVING Cláusula, a menos que incluídas numa função agregada.

a extensão da lista de selecção também se aplica a ORDER BY. Isto é, você pode se referir a colunas não agregadas na cláusula ORDER BY que não aparecem na cláusula GROUP BY. (No entanto, como mencionado anteriormente, ORDER BY não afectam os valores são escolhidos a partir de nonaggregated colunas; ele apenas ordena-los depois que eles foram escolhidos.) Esta extensão não se aplica se o modoONLY_FULL_GROUP_BY SQL estiver activo.

Se uma consulta tem funções de agregação e não GROUP BY cláusula, ele não pode ter nonaggregated colunas na lista de seleção, HAVING condição, ou ORDER BY lista ONLY_FULL_GROUP_BY habilitado:

mysql> SELECT name, MAX(age) FROM t;ERROR 1140 (42000): Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)with no GROUP columns is illegal if there is no GROUP BY clause

Sem GROUP BY, existe um único grupo e é não determinístico que name valor escolher para o grupo.

outra extensão MySQL para SQL padrão permite referências no HAVING cláusula para expressões aliadas na lista de seleção. A activação de ONLY_FULL_GROUP_BY evita isto. Por exemplo, a seguinte consulta retorna name valores que ocorrem apenas uma vez na tabela orders; a consulta é aceito independentemente de ONLY_FULL_GROUP_BY é habilitada:

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

a consulta A seguir é aceito somente se ONLY_FULL_GROUP_BY está desabilitada.

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

Se estiver a tentar seguir o padrão SQL, pode usar apenas expressões de coluna em GROUP BY cláusulas. Como uma solução alternativa, use um alias para a expressão:

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

o MySQL permite noncolumn expressões GROUP BY cláusulas, para que o alias é desnecessário:

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