返回每个组的最大值,但是当存在平局时,在 MySQL 中返回一个具有较低 id 的值
Posted
技术标签:
【中文标题】返回每个组的最大值,但是当存在平局时,在 MySQL 中返回一个具有较低 id 的值【英文标题】:return max value for each group but when there is a tie, return one with lower id in MySQL 【发布时间】:2021-03-17 18:21:26 【问题描述】:我正在使用 mysql 8.0
我的桌子是这样的:
group user_id score
A 1 33
B 2 22
A 3 22
B 4 22
我希望它返回
group user_id score
A 1 33
B 2 22
请注意,即使 B 组的分数相同,user_id=2 也是最终获胜者,因为他/她的 user_id 较低
如何从下面的查询中改进...?
SELECT group, user_id, max(score)
from table
提前致谢!
【问题讨论】:
请注意,GROUP 是 MySQL 中的保留字,因此不适合作为表/列标识符。 啊是的,这只是一个示例组列实际上是一个不同的名称,但感谢您指出! 【参考方案1】:@Ambleu 您使用MAX()
是在正确的轨道上,但要做到这一点,除了MIN()
之外,您还需要使用它,并且还需要使用子查询来获取MAX(score)
,如下所示:
SELECT `mt`.`group`,
MIN(`mt`.`user_id`) AS `user_id`,
`mt`.`score`
FROM `myTable` AS `mt`
JOIN (SELECT `group`,
MAX(`score`) AS `score`
FROM `myTable`
GROUP BY `group`) AS `der` ON `der`.`group` = `mt`.`group`
AND `der`.`score` = `mt`.`score`
GROUP BY `mt`.`group`, `mt`.`score`
Here are your tables and the solution query mocked up on db-fiddle.
如果这不能满足您的需求,请告诉我,我会尽力提供进一步帮助。
【讨论】:
太棒了!谢谢!【参考方案2】:在 MySQL 8.0 中,我会推荐窗口函数:
select grp, user_id, score
fom (
select t.*,
row_number() over(partition by grp order by score desc, user_id) rn
from mytable t
) t
where rn = 1
或者,您可以使用相关子查询进行过滤:
select t.*
from mytable t
where user_id = (
select t1.user_id
from mytable t1
where t1.grp = t.grp
order by t1.score desc, t1.user_id limit 1
)
第二个查询将利用(grp, score desc, user_id)
上的索引。
旁注:group
是语言关键字,因此不适合作为列名。我在查询中将其重命名为grp
。
【讨论】:
提及窗口函数的好主意,赞成以上是关于返回每个组的最大值,但是当存在平局时,在 MySQL 中返回一个具有较低 id 的值的主要内容,如果未能解决你的问题,请参考以下文章