Luc*_*sBr 3 mysql group-by greatest-n-per-group
我有下foo
表:
+----+--------+-------+
| id | name | qty |
+----+--------+-------+
| 1 | John | 3 |
| 2 | John | 1 |
| 3 | Mary | 5 |
| 4 | Mary | 2 |
| 5 | Gary | 3 |
| 6 | Gary | 4 |
| 7 | Gary | 5 |
+----+--------+-------+
Run Code Online (Sandbox Code Playgroud)
我只想选择id
和name
最小Qty
分组 by name
,结果如下:
+----+--------+
| id | name |
+----+--------+
| 2 | John |
| 4 | Mary |
| 5 | Gary |
+----+--------+
Run Code Online (Sandbox Code Playgroud)
我能做到这一点的唯一方法是通过以下操作:
SELECT id, name FROM (SELECT id, name, MIN(qty) FROM foo GROUP BY name) AS a;
Run Code Online (Sandbox Code Playgroud)
有没有更“美丽”(或更少冗余)的方法来做到这一点?
如您所述,如果没有子选择,则无法完成此操作。
有两个步骤。
1. 对于每个名称,找到具有 MIN(qty) 的记录。
2. 返回该记录的 ID。
还有其他方法,但两个步骤仍然存在。
您发布的查询似乎缺少一些信息。这应该是整件事。
SELECT id, name
FROM (
SELECT name, MIN(qty) minqty
FROM foo fs
GROUP BY name
) AS a
JOIN foo f
ON f.name = fs.name
AND f.qty = fs.minqty
Run Code Online (Sandbox Code Playgroud)
您的查询使用部分组。这在旧版本的 MySQL 中是允许的(使用默认设置),并且多年来可能造成了很多痛苦和神秘的错误。看看为什么会发生这种情况。考虑:
select id, name, min(qty) from foo group by name;
+----+------+----------+
| id | name | min(qty) |
+----+------+----------+
| 1 | John | 1 |
| 3 | Mary | 2 |
+----+------+----------+
Run Code Online (Sandbox Code Playgroud)
如图所示,结果中有一个与数量无关的id,为什么?由于您仅按名称分组,因此每个名称有两个 ID 可供选择。MySQL 会从这些组中随机为 John 和 Mary 选择一个 id,结果有时是正确的,有时是不正确的。您需要做的是为每个名称选择最少数量,然后使用该数量和名称查找与之关联的 id。@Kondybas 和 @Shooter-McGavin 都在他们的回答中展示了如何做到这一点。