Para evitar resultados potencialmente inesperados cuando se usa GROUP BY
sin una función agregada, como se usa en la respuesta aceptada , porque MySQL es libre de recuperar CUALQUIER valor dentro del conjunto de datos que se agrupa cuando no se usa una función agregada [sic] y problemas conONLY_FULL_GROUP_BY
. Considere usar una unión de exclusión.
Exclusion Join - Entidades inequívocas
Suponiendo que el nombre y el apellido están indexados de manera exclusiva (sin ambigüedades) , una alternativa GROUP BY
es ordenarlos usando unLEFT JOIN
para filtrar el conjunto de resultados, también conocido como exclusión JOIN.
Ver demostración
Orden ascendente (AZ)
Para recuperar el nombre distintivo ordenado por apellido de AZ
Consulta
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname > t2.lastname
WHERE t2.id IS NULL;
Resultado
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
Orden descendente (ZA)
Para recuperar el nombre distintivo ordenado por apellido de ZA
Consulta
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND t1.lastname < t2.lastname
WHERE t2.id IS NULL;
Resultado
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Luego puede ordenar los datos resultantes como desee.
Exclusion Join - Entidades ambiguas
Si la combinación de nombre y apellido no es única (ambigua) y tiene varias filas de los mismos valores, puede filtrar el conjunto de resultados al incluir una condición OR en los criterios de UNIR para también filtrar por id.
Ver demostración
datos de nombre_tabla
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
Consulta
SELECT t1.*
FROM table_name AS t1
LEFT JOIN table_name AS t2
ON t1.firstname = t2.firstname
AND (t1.lastname > t2.lastname
OR (t1.firstname = t1.firstname AND t1.lastname = t2.lastname AND t1.id > t2.id))
WHERE t2.id IS NULL;
Resultado
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
Subconsulta ordenada
EDITAR
Mi respuesta original usando una subconsulta ordenada , fue escrita antes de MySQL 5.7.5 , que ya no es aplicable, debido a los cambios conONLY_FULL_GROUP_BY
. Utilice los ejemplos de combinación de exclusión anteriores en su lugar.
También es importante tener en cuenta; cuando ONLY_FULL_GROUP_BY
está desactivado (comportamiento original anterior a MySQL 5.7.5) , el uso de GROUP BY
sin una función agregada puede producir resultados inesperados, porque MySQL es libre de elegir CUALQUIER valor dentro del conjunto de datos que se está agrupando [sic] .
Esto significa que se puede recuperar un valor ID
o que no está asociado con la fila recuperada .lastname
firstname
ADVERTENCIA
Con MySQL GROUP BY
puede no producir los resultados esperados cuando se usa conORDER BY
Ver ejemplo de caso de prueba
El mejor método de implementación, para garantizar los resultados esperados, es filtrar el alcance del conjunto de resultados utilizando una subconsulta ordenada.
datos de nombre_tabla
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
Consulta
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
Resultado
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
Comparación
Para demostrar los resultados inesperados cuando se usa GROUP BY
en combinación conORDER BY
Consulta
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
Resultado
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |