Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

O MySQL está quebrando o padrão ao permitir a seleção de colunas que não fazem parte da cláusula group by?


O SQL padrão rejeitaria sua consulta porque você não pode SELECIONAR campos não agregados que não fazem parte da cláusula GROUP BY em uma consulta agregada

Isso está correto, até 1992 .

Mas está claramente errado, de 2003 em diante.

Do padrão SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, de http ://www.wiscorp.com/ , parágrafo 7.12 (especificação da consulta), página 398 :
  1. Se T é uma tabela agrupada, então seja G o conjunto de colunas de agrupamento de T. Em cada ((expressão de valor)) contido em ((lista de seleção)) , cada referência de coluna que referencia uma coluna de T deve referenciar alguma coluna C que é funcionalmente dependente em G ou deve ser contido em um argumento agregado de um ((definir especificação de função))cuja consulta de agregação é QS

Agora, o MYSQL implementou esse recurso permitindo não apenas colunas que são funcionalmente dependentes nas colunas de agrupamento mas permitindo todas as colunas . Isso está causando alguns problemas com usuários que não entendem como funciona o agrupamento e obtêm resultados indeterminados onde não esperavam.

Mas você está certo em dizer que o MySQL adicionou um recurso que entra em conflito com os padrões SQL (embora você pareça pensar que pelo motivo errado). Não é totalmente preciso, pois eles adicionaram um recurso padrão SQL, mas não da melhor maneira (mais como a maneira mais fácil), mas entra em conflito com os padrões mais recentes.

Para responder à sua pergunta, a razão para este recurso do MySQL (extensão) é que eu suponho estar de acordo com os padrões SQL mais recentes (2003+). Por que eles escolheram implementá-lo dessa maneira (não totalmente compatível), só podemos especular.

Como @Quassnoi e @Johan responderam com exemplos, é principalmente uma questão de desempenho e manutenção. Mas não se pode alterar facilmente o RDBMS para ser inteligente o suficiente (exceto Skynet) para reconhecer colunas funcionalmente dependentes, então os desenvolvedores do MySQL fizeram uma escolha:

Nós (MySQL) damos a você (usuários do MySQL) esse recurso que está nos padrões SQL-2003. Melhora a velocidade em certos GROUP BY consultas, mas há um problema. Você precisa ter cuidado (e não o mecanismo SQL) para que as colunas no SELECT e TENDO listas são funcionalmente dependentes do GROUP BY colunas. Se não, você pode obter resultados indeterminados.

Se você quiser desativá-lo, você pode definir sql_mode para ONLY_FULL_GROUP_BY .

Está tudo nos documentos MySQL:Extensões para GRUPAR POR (5.5) - embora não no texto acima, mas como em sua citação (eles até esqueceram de mencionar que é um desvio do SQL-2003 padrão, embora não do SQL-92 padrão). Esse tipo de escolha é comum, eu acho, em todos os softwares, incluindo outros RDBMS. Eles são feitos para desempenho, compatibilidade com versões anteriores e muitos outros motivos. Oracle tem o famoso '' é o mesmo que NULL por exemplo, e o SQL-Server provavelmente também tem alguns.

Há também esta postagem no blog de Peter Bouman, onde a escolha dos desenvolvedores do MySQL é defendida:Desmascarando os mitos GROUP BY .

Em 2011, como @Mark Byers nos informou em um comentário (em uma pergunta relacionada no DBA.SE), O PostgreSQL 9.1 adicionou um novo recurso (data de lançamento:setembro de 2011) projetado para esta finalidade. É mais restritivo que a implementação do MySQL e mais próximo do padrão.

Mais tarde, em 2015, o MySQL anunciou que na versão 5.7, o comportamento foi aprimorado para estar em conformidade com o padrão e realmente reconhecer dependências funcionais (ainda melhor que a implementação do Postgres). A documentação:Manipulação MySQL de GROUP BY (5.7) e outra postagem no blog de Peter Bouman:MySQL 5.7.5:GROUP BY respeita as dependências funcionais!