mysql - 在 MySQL 8 中按类别显示前 N 行,在另一个类别中没有重复
问题描述
与此问题类似,我在 MySQL 8.0.15 中有下表:
CREATE TABLE golf_scores (id INT PRIMARY KEY AUTO_INCREMENT, person TEXT, score INT, age INT);
INSERT INTO golf_scores (person, score, age) VALUES ('Angela', 40, 25),('Angela', 45, 25),('Angela', 55, 25),('Peter',45, 32),('Peter',55,32),('Rachel', 65, 35),('Rachel',75,35),('Jeff',75, 16);
SELECT * FROM golf_scores;
+----+--------+-------+------+
| id | person | score | age |
+----+--------+-------+------+
| 1 | Angela | 40 | 25 |
| 2 | Angela | 45 | 25 |
| 3 | Angela | 55 | 25 |
| 4 | Peter | 45 | 32 |
| 5 | Peter | 55 | 32 |
| 6 | Rachel | 65 | 35 |
| 7 | Rachel | 75 | 35 |
| 8 | Jeff | 75 | 16 |
+----+--------+-------+------+
我们要选择以下“最佳”3 行:
+----+--------+-------+------+
| id | person | score | age |
+----+--------+-------+------+
| 1 | Angela | 40 | 25 |
| 4 | Peter | 45 | 32 |
| 6 | Rachel | 65 | 35 |
+----+--------+-------+------+
换句话说,最低的 3 个高尔夫球得分没有人重复,以及该行的其他列。我不担心关系;我仍然想要三个结果。
查询SELECT person, MIN(score) as min_score FROM golf_scores GROUP BY person ORDER BY min_score LIMIT 3;
给出了正确的行,但仅限于列person
和分数。当我尝试像这样修改它时:
SELECT id, person, MIN(score) as min_score, age FROM golf_scores GROUP BY person ORDER BY min_score LIMIT 3;
我收到此错误:
错误 1055 (42000):SELECT 列表的表达式 #1 不在 GROUP BY 子句中,并且包含在功能上不依赖于 GROUP BY 子句中的列的非聚合列“records.golf_scores.id”;这与 sql_mode=only_full_group_by 不兼容
我也尝试过消除重复名称,SELECT id, DISTINCT person, score, age FROM golf_scores ORDER BY score LIMIT 3
但出现错误
ERROR 1064 (42000):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的“DISTINCT person, score FROM golf_scores ORDER BY score LIMIT 3”附近使用正确的语法
如何在 MySQL 中获得所需的输出?
解决方案
使用row_number()
:
select t.*
from (select t.*, row_number() over (partition by person order by score) as seqnum
from golf_scores t
) t
where seqnum = 1
order by score asc
limit 3;
在旧版本中,您可以通过使用相关子查询来做到这一点,并且id
:
select gs.*
from golf_scores gs
where gs.id = (select gs2.id
from golf_scores gs2
where gs2.person = gs.person
order by gs2.score asc
limit 1
)
order by score asc
limit 3;
这也可能是索引 on 的最快方式golf_scores(person, score, id)
。
推荐阅读
- swift - 单击按钮时 UITextField 更改宽度
- python - 使用 Python 抓取与 Google 趋势 API
- javascript - 使用数组中的按钮传递值
- unity3d - ShaderLab Unity:使用 Surface Shader 将顶点渲染到 UV 空间
- python - 根据其他两个数组的前后元素的差异创建新数组
- ethereum - 为什么这些以太坊合约没有席卷 USDT?
- python - 当类错误具有不同权重时用于多类分类的自定义指标
- gstreamer - GStreamer 中的 0(零)帧率是什么意思?
- javascript - 如何通过数组Javascript拆分对象数组
- c++ - 为什么当我尝试在游戏中模拟鼠标移动时使用 c++ Input 类会导致 filck-move 进入地面(在游戏 ofc 中)?