为了避免潜在的意想不到的结果时,使用GROUP BY
不带聚合函数,作为公认的答案使用,因为MySQL是免费检索任何数据集内的值不使用聚合功能时被分组[原文]和问题进行ONLY_FULL_GROUP_BY
。请考虑使用排除联接。
排除联接-明确实体
假设名字和姓氏被唯一索引(明确),则另一种选择GROUP BY
是使用进行排序LEFT JOIN
以过滤结果集,否则称为排除JOIN。
见示范
升序(AZ)
从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;
结果
| id | firstname | lastname |
|----|-----------|----------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |
降序(ZA)
从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;
结果
| 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 |
有序子查询
编辑
我最初使用有序子查询的答案是在MySQL 5.7.5之前编写的,由于的更改,该版本不再适用ONLY_FULL_GROUP_BY
。请改用上面的排除联接示例。
注意也很重要;当ONLY_FULL_GROUP_BY
处于关闭状态(现有到MySQL 5.7.5原始行为),使用的GROUP BY
而无需聚合函数可以产生意外的结果,因为MySQL是自由选择任何数据集内的值被分组[原文如此]。
意味着可以检索与检索到的行不相关的ID
or或lastname
value 。firstname
警告
与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
结果
| ID | first | last |
|----|-------|---------|
| 2 | Bugs | Bunny |
| 3 | John | Johnson |
比较方式
GROUP BY
与结合使用时展示出意想不到的结果ORDER BY
询问
SELECT * FROM table_name GROUP BY FirstName ORDER BY ID DESC
结果
| ID | first | last |
|----|-------|-------|
| 2 | Bugs | Bunny |
| 1 | John | Doe |