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

Comportamiento de MySQL GROUP BY

MySQL elige una fila arbitrariamente. En la práctica, los motores de almacenamiento MySQL comúnmente utilizados devuelven los valores del primero fila en el grupo, con respecto al almacenamiento físico.

create table foo (id serial primary key, category varchar(10));

insert into foo (category) values 
  ('foo'), ('foo'), ('foo'), ('bar'), ('bar'), ('bar');

select * from foo group by category;

+----+----------+
| id | category |
+----+----------+
|  4 | bar      |
|  1 | foo      |
+----+----------+

Otras personas tienen razón en que MySQL le permite ejecutar esta consulta a pesar de que tiene resultados arbitrarios y potencialmente engañosos. El estándar SQL y la mayoría de los demás proveedores de RDBMS no permiten este tipo de consulta ambigua GROUP BY. Esto se llama la regla de valor único :todas las columnas en la lista de selección deben ser explícitamente parte de los criterios GROUP BY, o bien dentro de una función agregada, p. COUNT() , MAX() , etc.

MySQL admite un modo SQL ONLY_FULL_GROUP_BY eso hace que MySQL devuelva un error si intenta ejecutar una consulta que viola la semántica estándar de SQL.

AFAIK, SQLite es el único otro RDBMS que permite columnas ambiguas en una consulta agrupada. SQLite devuelve valores desde el último fila en el grupo:

select * from foo group by category;

6|bar
3|foo

Podemos imaginar consultas que no serían ambiguas, pero que violarían la semántica estándar de SQL.

SELECT foo.*, parent_of_foo.* 
FROM foo JOIN parent_of_foo 
  ON (foo.parent_id = parent_of_foo.parent_id) 
GROUP BY foo_id;

No hay forma lógica de que esto pueda producir resultados ambiguos. Cada fila en foo obtiene su propio grupo, si AGRUPAMOS POR la ​​clave principal de foo. Entonces, cualquier columna de foo puede tener solo un valor en el grupo. Incluso unirse a otra tabla a la que hace referencia una clave externa en foo puede tener solo un valor por grupo, si los grupos están definidos por la clave principal de foo.

MySQL y SQLite confían en usted para diseñar consultas lógicamente inequívocas. Formalmente, cada columna en la lista de selección debe ser una dependencia funcional de las columnas en el criterio GROUP BY. Si no se adhiere a esto, es su culpa. :-)

SQL estándar es más estricto y no permite algunas consultas que podrían ser inequívoco, probablemente porque sería demasiado complejo para que el RDBMS esté seguro en general.