2011-05-11 121 views
137
ID FirstName LastName 
1  John  Doe 
2  Bugs  Bunny 
3  John  Johnson 

我想选择从FirstNameDISTINCT结果,但我需要相应的IDLastNameMySQL的选择一列DISTINCT,与相应的其他列

结果集只需显示一个John,但其中ID是1和LastName

+1

你想要姓氏属于最低的ID与不同的名字? – 2011-05-11 15:57:07

+4

使用'GROUP BY'而不是 – diEcho 2011-05-11 15:57:12

+1

应该选择顶级的逻辑是什么?我想你会希望John Doe和John Johnson都出现,因为他们是两个不同的约翰,但那只是我。 – judda 2011-05-11 16:00:23

回答

137

尝试此查询

SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName) 
+32

这不适用于MySQL 5.5 – NullVoxPopuli 2011-10-13 19:23:33

+10

我们如何知道哪一行将被返回? – 2013-05-05 16:51:37

+18

@根据MySQL [文档](http://dev.mysql.com/doc/refman/5.1/en/group-by-extensions.html),你不可以:“服务器可以自由选择来自每个组的任何值,所以除非它们相同,否则选择的值是不确定的。“ 实际上,我已经成功地将这种查询与ORDER BY子句一起使用,例如,您可以添加ORDER BY id ASC/DESC,并且每次执行查询时MySQL都会返回一致的结果。但我会确定是否有人在生产环境中使用未公开的功能。 – 2013-06-03 14:54:43

44

DISTINCT关键字并不像您期待的那样真正起作用。当你使用SELECT DISTINCT col1, col2, col3时,你实际上选择了所有独特的{col1,col2,col3}元组。

+4

感谢Brian的指出。你能提供一个我如何利用GROUP BY获得相同结果的例子吗? – 2011-05-11 16:20:30

2

不知道你是否能与MySQL做到这一点,但你可以在T-SQL中使用一个CTE

; 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 

否则,你可能必须使用一个临时表。

20
SELECT ID,LastName 
From TABLE_NAME 
GROUP BY FirstName 
HAVING COUNT(*) >=1 
+2

加入'HAVING'让我的查询慢了50%。 – 2015-10-21 22:08:09

+0

有没有HAVING COUNT(*)> = 1的情况是错误的? – 2016-12-03 17:52:26

0
SELECT DISTINCT(firstName), ID, LastName from tableName GROUP BY firstName 

将是最好的选择海事组织。

+27

这将不起作用,它也将ID和姓氏纳入独特的评估。 – 2014-06-30 15:05:10

2
SELECT firstName, ID, LastName from tableName GROUP BY firstName 
-2

您可以使用group by来显示不同的值以及相应的字段。

select * from tabel_name group by FirstName 

现在,你有这样的输出:

ID FirstName  LastName 
2  Bugs   Bunny 
1  John   Doe 


如果你想回答这样

ID FirstName  LastName 
1  John   Doe 
2  Bugs   Bunny 

然后使用此查询,

select * from table_name group by FirstName order by ID 
+2

按订单进行分组时,这并不总是会产生预期结果 – fyrye 2014-09-30 15:35:31

38

编辑

原来的答案之前的MySQL 5.7.5,到原来的答案不再适用写入。需要注意的是,使用GROUP BY而没有聚合函数将会产生意想不到的结果,因为MySQL可以自由选择被分组的数据集中的任何值。

假设名字和姓氏是唯一索引的,GROUP BY的替代方法是使用LEFT JOIN来筛选结果集。See Demonstration

要检索截然不同的姓名由姓氏有序降序(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 | 

要检索截然不同的姓名由姓氏以升序(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 | 
有序

您可以根据需要订购产生的数据。 Test Case Example

警告

随着MySQL的GROUP BYORDER BY见使用时不会总是产生预期的效果。

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

表名数据

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

查询

SELECT * FROM (
    SELECT * FROM table_name ORDER BY ID DESC 
) AS t1 
GROUP BY FirstName 

#Results 
ID FirstName LastName 
2  Bugs  Bunny 
3  John  Johnson 

对战

SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC 

#Results 
ID FirstName LastName 
2  Bugs  Bunny 
1  John  Doe 
+2

迄今为止答案最全。在第一个查询中将'ID desc'更改为'ID asc'可以让我们检索'John Doe'或'John Johnson'。在第二个查询中更改'ID desc'不会产生这种效果。 – carla 2015-06-19 15:44:29

+0

在postgres上,您不需要确定mysql就需要在组中使用ID。 – 2015-08-20 14:04:55

0
select distinct (column1), column2 
from table1 
group by column1 
+1

'DISTINCT()'不是一个函数。另外DISTINCT和GROUP BY也在做同样的事情,所以没有理由把它们都放在一起。 – Marki555 2015-07-15 07:37:45

+0

这不是一个有效的声明,您应该使用DISTINCT或Group By而不是两者。 – heshanlk 2017-08-18 03:33:49

0

请记住,当使用该组和按顺序时,MySQL是唯一的数据库,允许在组中使用列和/或按顺序使用不属于select语句的部分。

因此,例如: 选择COLUMN1 从表 组由COLUMN2 ORDER BY栏3

这不会在其他数据库一样Postgres的,甲骨文,MSSQL,等飞你就必须做好以下这些数据库

选择列1,列2,列2通过 栏3从表 组 ORDER BY栏3

只是索姆如果您将当前代码迁移到另一个数据库或者开始在另一个数据库中工作并尝试重新使用代码,则需要提供信息。