MySQL选择一列DISTINCT,以及相应的其他列

m r*_*m r 182 mysql

ID   FirstName   LastName
1      John        Doe
2      Bugs        Bunny
3      John        Johnson
Run Code Online (Sandbox Code Playgroud)

我想DISTINCTFirstName列中选择结果,但我需要相应的IDLastName.

结果集只需显示一个John,但需要ID1和1 LastName的Doe.

diE*_*cho 177

试试这个查询

 SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName)
Run Code Online (Sandbox Code Playgroud)

  • 根据MySQL [文档](http://dev.mysql.com/doc/refman/5.1/en/group-by-extensions.html),你不能使用@Full Decent:"服务器可以自由选择任何每组的价值,所以除非它们相同,否则所选的价值是不确定的." 实际上,我已成功地将这种查询与ORDER BY子句一起使用,例如,您可以添加ORDER BY id ASC/DESC,并且每次执行查询时MySQL都会返回一致的结果.但我确定是否有人应该在生产环境中使用未记录的功能. (25认同)
  • 我们如何知道将返回哪一行? (14认同)
  • 这不适用于 only_full_group_by 模式,因为 ID 和 LastName 既不聚合也不属于分组功能的一部分。帮助! (6认同)
  • OP没有提到mysql版本. (2认同)
  • @sinaza 请参阅我对 MySQL `5.7.5+` 的更新答案,了解更改后的 [`GROUP BY` 处理](https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html ) (2认同)

Bri*_*oll 57

DISTINCT关键字并未真正发挥你期待它的方式.当你使用时,SELECT DISTINCT col1, col2, col3你实际上选择了所有唯一的{col1,col2,col3}元组.

  • 谢谢你指出Brian.您能举例说明如何利用GROUP BY获得相同的结果吗? (10认同)

fyr*_*rye 51

编辑

原始答案是在MySQL 5.7.5之前编写的,由于默认更改而不再适用ONLY_FULL_GROUP_BY.同样重要的是要注意,当ONLY_FULL_GROUP_BY禁用时,使用GROUP BY没有聚合函数将产生意外结果,因为MySQL可以自由选择被分组的数据集中的任何[原文如此].

假设firstname和lastname是唯一索引的,GROUP BY则可以使用a LEFT JOIN来对结果集进行排序.见示范

按降序检索由姓氏排序的不同名字(ZA)

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 |
Run Code Online (Sandbox Code Playgroud)

按升序检索由姓氏排序的不同名字(AZ)

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 |
Run Code Online (Sandbox Code Playgroud)

然后,您可以根据需要订购结果数据.

如果名字和姓氏组合不是唯一的并且您有多行具有相同值,则可以通过在联接上包含OR条件来筛选结果集以选择特定ID.看演示.

table_name数据:

(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson'),
(4, 'John', 'Doe'),
(5, 'John', 'Johnson')
Run Code Online (Sandbox Code Playgroud)
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 |
Run Code Online (Sandbox Code Playgroud)

警告

使用时,使用MySQL GROUP BY并不会总是产生预期的结果ORDER BY:参见:测试用例示例.

确保预期结果的最佳实现方法是使用像这样的子查询来过滤结果集范围.

table_name数据:

(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
Run Code Online (Sandbox Code Playgroud)

询问

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 |
Run Code Online (Sandbox Code Playgroud)

SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC

#Results
| ID | first |  last |
|----|-------|-------|
|  2 |  Bugs | Bunny |
|  1 |  John |   Doe |
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止最完整的答案.在第一个查询中将"ID desc"更改为"ID asc"允许我们检索"John Doe"或"John Johnson".在第二个查询中更改"ID desc"没有这种效果. (2认同)

小智 21

SELECT ID,LastName 
From TABLE_NAME 
GROUP BY FirstName 
HAVING COUNT(*) >=1
Run Code Online (Sandbox Code Playgroud)

  • 添加`HAVING`使我的查询慢了50%. (2认同)

小智 5

怎么样

`SELECT 
    my_distinct_column,
    max(col1),
    max(col2),
    max(col3)
    ...
 FROM
    my_table 
 GROUP BY 
    my_distinct_column`
Run Code Online (Sandbox Code Playgroud)

  • 在单个列分组中的多个列上使用聚合函数的问题是,“MAX()”将检索分组内的最高值,而不是 OP 所需的不同列的相应行值。[示例](https://www.db-fiddle.com/f/wJ8gtnSntvKcv31mgWWY9o/0) 期望“5, John, Johnson”,但收到“6, John, Johnson”,其中“ID 6”是“John, Doe” (2认同)