ID FirstName LastName
1 John Doe
2 Bugs Bunny
3 John Johnson
我想从FirstName列中选择DISTINCT结果,但我需要相应的ID和LastName。
结果集只需要显示一个John,但是ID为1,LastName为Doe。
ID FirstName LastName
1 John Doe
2 Bugs Bunny
3 John Johnson
我想从FirstName列中选择DISTINCT结果,但我需要相应的ID和LastName。
结果集只需要显示一个John,但是ID为1,LastName为Doe。
当前回答
不确定是否可以用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
否则,您可能不得不使用临时表。
其他回答
试试这个查询
SELECT ID, FirstName, LastName FROM table GROUP BY(FirstName)
如何
`SELECT
my_distinct_column,
max(col1),
max(col2),
max(col3)
...
FROM
my_table
GROUP BY
my_distinct_column`
为了避免在不使用聚合函数的情况下使用GROUP BY时可能出现的意想不到的结果,就像在接受的答案中使用的那样,因为MySQL在不使用聚合函数并且只有_full_group_by时可以自由地检索被分组的数据集中的任何值。请考虑使用排除连接。
排除连接-明确的实体
假设姓和名是唯一索引(无歧义),GROUP BY的另一种替代方法是使用LEFT JOIN筛选结果集,也称为排除JOIN。
看到演示
升序(A-Z)
从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;
结果
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
降序(Z-A)
从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;
结果
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
然后可以根据需要对结果数据进行排序。
排除连接-模糊实体
如果姓和名的组合不是唯一的(不明确),并且有多个相同值的行,则可以通过在JOIN条件上包含OR条件来过滤结果集,也可以通过id进行过滤。
看到演示
table_name数据
(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;
结果
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
复合IN()子查询-明确的实体
对于较大的数据集,使用排除连接可能非常慢。 如果有明确的条目,另一种方法是对MIN/MAX聚合子查询使用Composite IN()标准。
示范
升序(A-Z)
查询
SELECT t1.*
FROM table_name AS t1
WHERE (t1.firstname, t1.lastname) IN(
SELECT firstname, MIN(lastname)
FROM table_name
GROUP BY firstname
)
结果
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
降序(Z-A)
查询
SELECT t1.*
FROM table_name AS t1
WHERE (t1.firstname, t1.lastname) IN(
SELECT firstname, MAX(lastname)
FROM table_name
GROUP BY firstname
)
结果
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
复合IN()依赖子查询-不明确的实体
通过在id列上添加带有MIN/MAX的依赖子查询,可以将相同的理论从Ambiguous Exclusion连接应用到复合IN()子查询方法。
示范
查询
SELECT t1.*
FROM table_name AS t1
WHERE t1.id IN(
SELECT MIN(id)
FROM table_name
WHERE (t1.firstname, t1.lastname) IN(
SELECT firstname, MIN(lastname)
FROM table_name
GROUP BY firstname
)
GROUP BY firstname, lastname
);
结果
| id | firstname | lastname |
|----|-----------|----------|
| 1 | John | Doe |
| 2 | Bugs | Bunny |
命令子查询
EDIT
我最初使用有序子查询的答案是在MySQL 5.7.5之前编写的,由于ONLY_FULL_GROUP_BY的变化,它不再适用。请用上面的例子代替。
同样重要的是要注意;当ONLY_FULL_GROUP_BY被禁用时(MySQL 5.7.5之前的原始行为),使用GROUP BY而不使用聚合函数可能会产生意想不到的结果,因为MySQL可以在被分组的数据集中自由选择任何值[原文]。
这意味着可以检索与所检索的姓名行不关联的ID或姓值。
警告
在MySQL中,GROUP BY在使用ORDER BY时可能不会产生预期的结果
参见测试用例示例
确保预期结果的最佳实现方法是使用有序子查询筛选结果集范围。
table_name数据
(1, 'John', 'Doe'),
(2, 'Bugs', 'Bunny'),
(3, 'John', 'Johnson')
查询
SELECT * FROM (
SELECT * FROM table_name ORDER BY ID DESC
) AS t1
GROUP BY FirstName
结果(MySQL 5.6)
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
比较
演示GROUP BY与ORDER BY结合使用时的意外结果
查询
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
结果(MySQL 5.6)
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
SELECT DISTINCT (column1), column2
FROM table1
GROUP BY column1
SELECT firstName, ID, LastName from tableName GROUP BY firstName