sql >> Base de Datos >  >> RDS >> Mysql

¿MySQL está rompiendo el estándar al permitir seleccionar columnas que no forman parte de la cláusula group by?

SQL estándar rechazaría su consulta porque no puede SELECCIONAR campos no agregados que no forman parte de la cláusula GROUP BY en una consulta agregada

Esto es correcto, hasta 1992 .

Pero es claramente incorrecto, desde 2003 y más allá.

Del estándar SQL-2003, 6IWD6-02-Foundation-2011-01.pdf, de http ://www.wiscorp.com/ , párrafo 7.12 (especificación de consulta), página 398 :

  1. Si T es una tabla agrupada, entonces sea G el conjunto de columnas de agrupación de T. En cada ((expresión de valor)) contenida en ((lista de selección)), cada referencia de columna que hace referencia a una columna de T hará referencia a alguna columna C que es funcionalmente dependiente en G o estará contenido en un argumento agregado de una ((especificación de función establecida)) cuya consulta de agregación es QS

Ahora MYSQL ha implementado esta función al permitir no solo columnas que son funcionalmente dependientes en las columnas de agrupación pero permitir todas las columnas . Esto está causando algunos problemas con los usuarios que no entienden cómo funciona la agrupación y obtienen resultados indeterminados donde no los esperan.

Pero tiene razón al decir que MySQL ha agregado una función que entra en conflicto con los estándares de SQL (aunque parece pensar que es por el motivo equivocado). No es del todo exacto, ya que han agregado una función estándar de SQL, pero no de la mejor manera (más bien de la manera fácil), pero sí entra en conflicto con los últimos estándares.

Para responder a su pregunta, supongo que el motivo de esta característica (extensión) de MySQL es que cumple con los últimos estándares SQL (2003+). Por qué eligieron implementarlo de esta manera (no totalmente compatible), solo podemos especular.

Como @Quassnoi y @Johan respondieron con ejemplos, es principalmente un problema de rendimiento y mantenimiento. Pero uno no puede cambiar fácilmente el RDBMS para que sea lo suficientemente inteligente (excluido Skynet) para reconocer columnas funcionalmente dependientes, por lo que los desarrolladores de MySQL tomaron una decisión:

Nosotros (MySQL) le brindamos (usuarios de MySQL) esta característica que se encuentra en los estándares SQL-2003. Mejora la velocidad en ciertos GROUP BY consultas, pero hay una trampa. Debe tener cuidado (y no el motor SQL) para que las columnas en SELECT y HAVING las listas dependen funcionalmente del GROUP BY columnas De lo contrario, puede obtener resultados indeterminados.

Si desea deshabilitarlo, puede configurar sql_mode a ONLY_FULL_GROUP_BY .

Todo está en los docs de MySQL:Extensiones a GROUP BY (5.5) - aunque no en la redacción anterior sino como en su cita (incluso se olvidaron de mencionar que es una desviación del estándar SQL-2003 aunque no del estándar SQL-92). Creo que este tipo de opciones es común en todo el software, incluidos otros RDBMS. Están hechos para el rendimiento, la compatibilidad con versiones anteriores y muchas otras razones. Oracle tiene el famoso '' is the same as NULL por ejemplo, y SQL-Server probablemente también tenga algunos.

También hay esta publicación de blog de Peter Bouman, donde se defiende la elección de los desarrolladores de MySQL:Desmentir los mitos de GRUPO POR .

En 2011, como @Mark Byers nos informó en un comentario (en una pregunta relacionada en DBA.SE), PostgreSQL 9.1 agregó una nueva función (fecha de lanzamiento:septiembre de 2011) diseñado para este propósito. Es más restrictivo que la implementación de MySQL y más cercano al estándar.

Más tarde, en 2015, MySQL anunció que en la versión 5.7, el comportamiento se mejoró para cumplir con el estándar y reconocer dependencias funcionales (incluso mejor que la implementación de Postgres). La documentación:Manejo MySQL de GROUP BY (5.7) y otra publicación de blog de Peter Bouman:MySQL 5.7.5:GROUP BY respeta las dependencias funcionales!