2009-10-29 32 views
13

Dada la siguiente tabla 'foo'GRUPO POR MySQL comportamiento

ID | First Name | Last Name 
---------------------------- 
67 John  Smith 
---------------------------- 
67 Bill  Jacobs 

Lo first_name y last_name hará la siguiente consulta de retorno y por qué?

SELECT * FROM foo WHERE ID = 67 GROUP BY ID 

Respuesta

0

Es muy probable que se seleccione el primer y el último nombre de la fila (última).

Puede agregar una cláusula ORDER BY para dar pistas sobre cómo desea ordenar las filas agrupadas.

+2

No, MySQL devuelve los valores de la primera fila del grupo. ORDER BY se aplica a las filas una vez formados los grupos; no afecta en absoluto el orden de las filas dentro del grupo. –

+0

Estoy corregido :) – Charles

4

El grupo de MySQL por no es consistente con el comportamiento estándar de SQL, MySQL hace que sea fácil obtener otras columnas PERO, al mismo tiempo, nunca puede estar seguro de cuál obtendrá.

Actualización: referirse a esta página: http://dev.mysql.com/doc/refman/5.0/en/group-by-handling.html

Al usar esta función, todas las filas de cada grupo deben tener los mismos valores para las columnas que están omitidos de la parte GROUP BY. El servidor está libre para devolver cualquier valor del grupo, por lo que los resultados son indeterminados a menos que todos los valores sean los mismos.

0

En SQL estándar, este SQL falla, con un error del procesador del servidor algo así como

"nombre y apellido no puede ser incluido en la cláusula select a menos que también están en el grupo A, o son parte de una función agregada ".

¿MySql realmente devuelve datos para esto?

+0

Sí, MySQL te permite hacer esto – Greg

3

No está definido, por lo que lo obtendrás.

Siempre me he preguntado por qué se permitía este comportamiento. Realmente, desearía que ese código genere un error (preferiblemente, uno descifrable, ninguno de los usuales de MySQL "su declaración tiene un problema, pero no sé dónde").

26

MySQL elige una fila arbitrariamente. En la práctica, los motores de almacenamiento MySQL de uso común devuelven los valores de la primera 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 son correctas que MySQL le permite ejecutar esta consulta a pesar de que cuenta con resultados arbitrarios y pueden inducir a error. El estándar SQL, y la mayoría de los demás proveedores RDBMS, no permiten este tipo de consulta GROUP BY ambigua. Esto se llama Regla de valor único: todas las columnas en la lista de selección deben ser parte explícita de los criterios GROUP BY, o bien dentro de una función agregada, p. COUNT(), MAX(), etc.

MySQL soporta un modo SQL ONLY_FULL_GROUP_BY que hace que MySQL devuelve un error si se intenta ejecutar una consulta que viola la semántica estándar SQL.

AFAIK, SQLite es el único otro RDBMS que permite columnas ambiguas en una consulta agrupada.SQLite devuelve valores de la última filaen el grupo:

select * from foo group by category; 

6|bar 
3|foo 

Podemos imaginar consultas que no serían ambiguas, y aún así violar la semántica estándar 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 una forma lógica de que esto pueda producir resultados ambiguos. Cada fila en foo obtiene su propio grupo, si agrupamos por la clave primaria 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 foránea en foo puede tener solo un valor por grupo, si los grupos están definidos por la clave primaria de foo.

MySQL y SQLite confían en que diseñe consultas lógicamente no ambiguas. Formalmente, cada columna en la lista de selección debe ser una dependencia funcional de las columnas en los criterios 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ívocas, probablemente porque sería demasiado complejo para que el RDBMS sea seguro en general. grupo

+3

Deberías obtener un premio nobel por esta respuesta. – Kermit

0

MySQLs por no es consistente con el comportamiento estándar SQL, MySQL hace que sea fácil de conseguir otras columnas, pero al mismo tiempo u nunca puede estar seguro de que uno u conseguirá.

Es cierto. En realidad, corresponde más al modo SELECT DISTINCT ON en postgres, por ejemplo, excepto que esto le permite especificar el orden de las filas antes de la distinción (?) Y, por lo tanto, qué fila obtendrá (es decir, más reciente, más antigua, lo que sea).

Nota MySQL en modo "compatible con sql" rechazará GROUP BY con columnas no especificadas como en su ejemplo.

Cuestiones relacionadas