类似于this question,我在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
和score`。当我尝试像这样修改它时:
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子句中,并且包含未聚合的列'records.golf_scores.id',该列在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by
不兼容
我还尝试使用SELECT id, DISTINCT person, score, age FROM golf_scores ORDER BY score LIMIT 3
消除重复的名称,但出现错误
错误1064(42000):您的SQL语法有错误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在第1行“ DISTINCT人,从golf_scores ORDER BY得分极限3”附近得分
如何在MySQL中获得所需的输出?
答案 0 :(得分:1)
使用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;
这也许也是在golf_scores(person, score, id)
上建立索引的最快方法。
答案 1 :(得分:1)
这是一种方法:
SELECT x.*
FROM golf_scores x
JOIN
( SELECT MIN(id) id FROM
( SELECT a.*
FROM golf_scores a
JOIN
( SELECT person, MIN(score) score FROM golf_scores GROUP BY person ) b
ON b.person = a.person
AND b.score = a.score
) n
GROUP
BY person
, score
) y
ON y.id = x.id
ORDER
BY x.score LIMIT 3;