问题
I have the following table in MySQL 8.0.15:
CREATE TABLE golf_scores (person TEXT, score INT);
INSERT INTO golf_scores VALUES ('Angela', 40),('Angela', 45),('Angela', 55),('Peter',45),('Peter',55),('Rachel', 65),('Rachel',75),('Jeff',75);
SELECT * FROM golf_scores;
+--------+-------+
| person | score |
+--------+-------+
| Angela | 40 |
| Angela | 45 |
| Angela | 55 |
| Peter | 45 |
| Peter | 55 |
| Rachel | 65 |
| Rachel | 75 |
| Jeff | 75 |
+--------+-------+
I am trying to get the following top 3 scores:
SELECT * FROM golf_scores;
+--------+-------+
| person | score |
+--------+-------+
| Angela | 40 |
| Peter | 45 |
| Rachel | 65 |
+--------+-------+
In other words, I want the best (lowest) 3 golf score without having duplicates by person. I'm not worried about ties; I'd still just like three results.
I thought this query would do it:
SELECT person, MIN(score) FROM golf_scores GROUP BY person ORDER BY score LIMIT 3;
but I get the following error:
ERROR 1055 (42000): Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'records.golf_scores.score' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
Adding score
to the GROUP BY
list just returns the lowest 3 scores total, regardless of duplicates in the person
column.
How can I get the desired output in MySQL?
回答1:
since order by clause is executed after select clause,try putting an aliases for min(score) .
SELECT person, MIN(score) as min_score FROM golf_scores GROUP BY person ORDER BY min_score LIMIT 3;
回答2:
You can try using row_number()
select * from
(
SELECT person, score,row_number() over(partition by person order by score) as rn
FROM golf_scores
)A where rn=1
ORDER BY score LIMIT 3
来源:https://stackoverflow.com/questions/54702226/show-top-n-scores-in-mysql-8-without-duplicates-by-category