ID FirstName LastName
1 John Doe
2 Bugs Bunny
3 John Johnson
Quiero seleccionar DISTINCT
resultados de la FirstName
columna, pero necesito el correspondiente ID
yLastName
.
El conjunto de resultados solo debe mostrar uno John
, pero con un ID
1 y un LastName
Doe.
DISTINCT
No es una función. Todas las respuestas conDISTINCT()
están mal. El error aparecerá cuando no lo coloques despuésSELECT
.ALL
las respuestas que usan paréntesis después de la palabra distinta son realmente incorrectas. Distinct NO es una función, por lo que no puede aceptar un parámetro. Los paréntesis que siguen a distintos simplemente se ignoran. A menos que esté utilizando PostgreSQL donde los paréntesis formarán un "tipo de datos complejo"Respuestas:
prueba esta consulta
fuente
5.7.5+
para elGROUP BY
manejoLa
DISTINCT
palabra clave realmente no funciona de la manera que espera. Cuando lo usaSELECT DISTINCT col1, col2, col3
, de hecho, está seleccionando todas las tuplas únicas {col1, col2, col3}.fuente
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
Resultado
Orden descendente (ZA)
Para recuperar el nombre distintivo ordenado por apellido de ZA
Consulta
Resultado
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
Consulta
Resultado
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 con
ONLY_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 deGROUP 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
Consulta
Resultado
Comparación
Para demostrar los resultados inesperados cuando se usa
GROUP BY
en combinación conORDER BY
Consulta
Resultado
fuente
Ordering is done after grouping.
, entonces No no en este caso de uso, además MariaDB ignora ORDER BY en subconsultas (según el estándar SQL) sin aLIMIT
. Desea utilizar unWindow Function
Para obtener más aclaraciones, debe hacer su pregunta en el intercambio de pila DBA , ya que esta es una pregunta relacionada con MySQLGROUP BY
pueden seleccionar cualquier valor dentro del conjunto de datos agrupados, a menos que se use una función de agregado en esas columnas para forzar un valor específico. Entonces,lastname
oid
puede provenir de cualquiera de las filas ordenadas. El ejemplo de subconsulta original era aceptable por defecto,MySQL <= 5.7.4
pero técnicamente aún sufre el problema. Si bienORDER BY
ayuda a evitar una selección aleatoria, todavía es teóricamente posible, pero con una probabilidad significativamente menor que sin usar laORDER BY
subconsulta.fuente
HAVING
hizo mi consulta un 50% más lenta.fuente
Qué tal si
fuente
No estoy seguro si puede hacer esto con MySQL, pero puede usar un CTE en T-SQL
De lo contrario, es posible que deba usar una tabla temporal.
fuente
Como señaló fyrye , la respuesta aceptada corresponde a versiones anteriores de MySQL en las que
ONLY_FULL_GROUP_BY
aún no se habían introducido. Con MySQL 8.0.17 (usado en este ejemplo), a menos que deshabiliteONLY_FULL_GROUP_BY
, recibirá el siguiente mensaje de error:Una forma de evitar esto no mencionada por fyrye , pero descrita en https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html , es aplicar la
ANY_VALUE()
función a las columnas que están no en laGROUP BY
cláusula (id
ylastName
en este ejemplo):Como está escrito en los documentos antes mencionados,
fuente
ANY_VALUE()
mi respuesta y mis comentarios se centren en evitar conjuntos de resultados ambiguos e impredecibles. Dado que, como sugiere el nombre de la función, podría recuperarse cualquier valor de las filas seleccionadas. Sugeriría usarMAX
o en suMIN
lugar.Tenga en cuenta al usar el grupo por y ordenar por que MySQL es la ÚNICA base de datos que permite que las columnas se usen en el grupo por y / o ordenar por pieza que no son parte de la instrucción select.
Entonces, por ejemplo: seleccione la columna1 del grupo de tablas por columna2, ordene por columna3
Eso no volará en otras bases de datos como Postgres, Oracle, MSSQL, etc. Debería hacer lo siguiente en esas bases de datos
seleccione column1, column2, column3 del grupo de tablas por column2 ordene por column3
Solo información en caso de que alguna vez migre su código actual a otra base de datos o comience a trabajar en otra base de datos e intente reutilizar el código.
fuente
Puede usar group by para mostrar valores distintos y también los campos correspondientes.
Ahora tienes una salida como esta:
Si quieres responder como
luego usa esta consulta,
fuente
Sería la mejor apuesta de la OMI
fuente
fuente
DISTINCT()
No es una función. También DISTINCT y GROUP BY están haciendo lo mismo, así que no hay razón para ponerlos a ambos.