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

¿Qué DBMS permite ordenar por un atributo que no está presente en la cláusula de selección?

Su consulta es sintaxis perfectamente legal, puede ordenar por columnas que no están presentes en la selección.

Si necesita las especificaciones completas sobre el orden legal, en SQL Standard 2003 tiene una larga lista de declaraciones sobre lo que debe y no debe contener el orden (02-Foundation, página 415, sección 7.13 , sub parte 28). Esto confirma que su consulta es sintaxis legal.

Creo que su confusión podría deberse a la selección y/u ordenación por columnas que no están presentes en el grupo por, u ordenación por columnas que no están en la selección cuando se usa distinto.

Ambos tienen el mismo problema fundamental, y MySQL es el único que yo sepa que lo permite.

El problema es este, que cuando se usa group by o distinto, las columnas que no están contenidas en ninguna de las dos no son necesarias, por lo que no importa si tienen múltiples valores diferentes en las filas porque nunca son necesarias. Imagina este simple conjunto de datos:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |
2   |    A    |    Z     |
3   |    B    |    Y     |

Si escribes:

SELECT  DISTINCT Column1
FROM    T;

Obtendrías

 Column1 
---------
     A   
     B   

Si luego agrega ORDER BY Column2 , ¿cuál de las dos columnas 2 usaría para ordenar A por, X o Z? No es determinista en cuanto a cómo elegir un valor para la columna 2.

Lo mismo se aplica a la selección de columnas que no están en el grupo por. Para simplificar las cosas, imagina las dos primeras filas de la tabla anterior:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |
2   |    A    |    Z     |

En MySQL puedes escribir

SELECT  ID, Column1, Column2
FROM    T
GROUP BY Column1;

Esto en realidad rompe el estándar SQL, pero funciona en MySQL, sin embargo, el problema es que no es determinista, el resultado:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |

No es ni más ni menos correcto que

ID  | Column1 | Column2  |  
----|---------+----------|
2   |    A    |    Y     |

Entonces, lo que estás diciendo es dame una fila para cada valor distinto de Column1 , que ambos conjuntos de resultados satisfacen, entonces, ¿cómo sabe cuál obtendrá? Pues no, parece ser un concepto erróneo bastante popular que se puede agregar y ORDER BY cláusula para influir en los resultados, por ejemplo, la siguiente consulta:

SELECT  ID, Column1, Column2
FROM    T
GROUP BY Column1
ORDER BY ID DESC;

Se aseguraría de obtener el siguiente resultado:

ID  | Column1 | Column2  |  
----|---------+----------|
2   |    A    |    Y     |

debido al ORDER BY ID DESC , sin embargo, esto no es cierto (como se demuestra aquí ).

Los documentos MySQL estado:

Entonces, aunque tenga un orden, esto no se aplica hasta que se haya seleccionado una fila por grupo, y esta fila no es determista.

SQL-Standard permite columnas en la lista de selección que no están contenidas en GROUP BY o una función agregada, sin embargo, estas columnas deben depender funcionalmente de una columna en GROUP BY. Desde SQL-2003-Standard (5WD-02-Foundation-2003-09 - página 346) - http ://www.wiscorp.com/sql_2003_standard.zip

Por ejemplo, el ID en la tabla de ejemplo es PRIMARY KEY, por lo que sabemos que es único en la tabla, por lo que la siguiente consulta se ajusta al estándar SQL y se ejecutaría en MySQL y fallaría en muchos DBMS actualmente (en el momento de escribir Postgresql es el DBMS más cercano que conozco para implementar correctamente el estándar - Ejemplo aquí ):

SELECT  ID, Column1, Column2
FROM    T
GROUP BY ID;

Dado que el ID es único para cada fila, solo puede haber un valor de Column1 para cada ID, un valor de Column2 no hay ambigüedad sobre qué devolver para cada fila.