MySQL selecciona una columna DISTINTA, con otras columnas correspondientes


ID   FirstName   LastName
1      John        Doe
2      Bugs        Bunny
3      John        Johnson

Quiero seleccionar DISTINCT resultados de la columna FirstName, pero necesito los ID y LastName correspondientes.

El conjunto de resultados necesita mostrar solo uno John, pero con un ID de 1 y un LastName de Doe.

 152
Author: SchmitzIT, 2011-05-11

10 answers

Pruebe esta consulta

 SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName)
 148
Author: diEcho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-04 05:08:59

La palabra clave DISTINCT realmente no funciona de la manera que esperas. Cuando utiliza SELECT DISTINCT col1, col2, col3, de hecho, está seleccionando todas las tuplas únicas {col1, col2, col3}.

 47
Author: Brian Driscoll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-11 15:57:08

EDITAR

La respuesta original se escribió antes de MySQL 5.7.5 , que ya no se aplica debido a los cambios predeterminados con ONLY_FULL_GROUP_BY. También es importante tener en cuenta que cuando ONLY_FULL_GROUP_BY está desactivado, el uso de GROUP BY sin una función de agregado producirá resultados inesperados, ya que MySQL es libre de elegir CUALQUIER valor dentro del conjunto de datos que se agrupa [sic].

Asumiendo que el firstname y el lastname están unívocamente indexados, la alternativa a GROUP BY es ordenar usando un LEFT JOIN para filtrar el conjunto de resultados. Ver Demostración

Para recuperar el firstname distinto ordenado por lastname en orden descendente (Z-A)

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;

#Results
| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  3 |      John |  Johnson |

Para recuperar el firstname distinto ordenado por lastname en orden ascendente (A-Z)

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;

#Results
| id | firstname | lastname |
|----|-----------|----------|
|  2 |      Bugs |    Bunny |
|  1 |      John |      Doe |

Luego puede ordenar los datos resultantes como desee.

Si la combinación de nombre y apellido no es única y tiene varias filas de la misma valores, puede filtrar el conjunto de resultados incluyendo una condición OR en la combinación para elegir un id específico. Ver la demostración.

nombre de la tabla data :

(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
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;

#Results
| id | firstname | lastname |
|----|-----------|----------|
|  1 |      John |      Doe |
|  2 |      Bugs |    Bunny |

ADVERTENCIA

Con MySQL GROUP BY no siempre dará los resultados esperados cuando se usa con ORDER BY Ver: Ejemplo de Caso de prueba.

El mejor método de implementación para garantizar los resultados esperados es filtrar el ámbito del conjunto de resultados utilizando una subconsulta como tan.

nombre de la tabla data :

(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

#Results
| ID | first |    last |
|----|-------|---------|
|  2 |  Bugs |   Bunny |
|  3 |  John | Johnson |

Versus

SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC

#Results
| ID | first |  last |
|----|-------|-------|
|  2 |  Bugs | Bunny |
|  1 |  John |   Doe |
 43
Author: fyrye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-13 22:44:26
SELECT ID,LastName 
From TABLE_NAME 
GROUP BY FirstName 
HAVING COUNT(*) >=1
 21
Author: sarath,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-03 11:31:31

No estoy seguro de si puede hacer esto con MySQL, pero puede usar un CTE en T-SQL

; WITH tmpPeople AS (
 SELECT 
   DISTINCT(FirstName),
   MIN(Id)      
 FROM People
)
SELECT
 tP.Id,
 tP.FirstName,
 P.LastName
FROM tmpPeople tP
JOIN People P ON tP.Id = P.Id

De lo contrario, es posible que tenga que usar una tabla temporal.

 2
Author: Thomas Langston,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-11 16:07:04
SELECT firstName, ID, LastName from tableName GROUP BY firstName
 2
Author: Nanhe Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-14 06:27:13

Tenga en cuenta al usar group by y order by que MySQL es la ÚNICA base de datos que permite el uso de columnas en el group by y/o order by piece que no forman parte de la instrucción select.

Por ejemplo: seleccionar columna1 de la tabla grupo por column2 ordenar por column3

Que no volará en otras bases de datos como Postgres, Oracle, MSSQL, etc. Usted tendría que hacer lo siguiente en esas bases de datos

Seleccionar columna1, columna2, columna3 de la tabla agrupar por column2 ordenar por column3

Solo algo de 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.

 0
Author: Antonio Delacruz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-01 21:56:53

Puede usar agrupar por para mostrar valores distintos y también los campos correspondientes.

select * from tabel_name group by FirstName

Ahora tienes una salida como esta:

ID    FirstName     LastName
2     Bugs          Bunny
1     John          Doe


Si quieres responder como

ID    FirstName     LastName
1     John          Doe
2     Bugs          Bunny

Luego use esta consulta,

select * from table_name group by FirstName order by ID
 -2
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-24 18:39:23
SELECT DISTINCT(firstName), ID, LastName from tableName GROUP BY firstName

Sería la mejor apuesta IMO.

 -3
Author: Monty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-17 16:00:26
select distinct (column1), column2
from table1
group by column1
 -4
Author: mack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-15 11:55:57