按列分组并选择具有多个最小值的行中的所有字段

Posted

技术标签:

【中文标题】按列分组并选择具有多个最小值的行中的所有字段【英文标题】:Group by column and select all fields in rows with multiple minimum values 【发布时间】:2021-11-28 17:31:00 【问题描述】:

我需要选择一行中由某个字段分组并包含另一个字段(点)的最小值的所有字段,使用另一个字段来打破平局(id)。

数据示例:

id game points hash
1 x 5 ax8
1 z 4 bc4
2 y 2 df8
2 x 1 fd8
3 x 2 fda0
3 y 2 fzlf
3 z 2 z89w

期望的结果:

id game point hash
2 x 1 fd8
2 y 2 df8
3 z 2 z89w

所以我想返回每场比赛的最低得分行和得分的 id。请注意,如果出现平局,例如在游戏 y 中 id 3 和 2 都得 2 分,我想要 id 为 2 的行。在实际表格中,有更多包含相关数据的字段。

当前解决方案:

SELECT g1.*
FROM games g1
  INNER JOIN
  (
    SELECT game, MIN(Point) MinPoint
    FROM games g2
    GROUP BY game
  ) g2
  ON g1.game = g2.game AND g1.point = g2.MinPoint

但是,我得到重复的行,其中两个 id 在游戏中得分相同。

【问题讨论】:

您需要在另一个级别重复此结构,以选择按游戏和积分分组的具有最小 ID 的行。 【参考方案1】:

ROW_NUMBER对你的行进行排名:

select id, game, points
from
(
  select
    g.*,
    row_number() over (partition by game
                       order by points, id) as rn
  from games g
) ranked
where rn = 1
order by game;

这需要 mysql 8。

另一种解决方案:选择所有不存在更好行的行。

select *
from games g
where not exist
(
  select null
  from games g2
  where g2.game = g.game
  and
  (
    g2.points < g.points
    or
    (g2.points = g.points and g2.id < g.id)
  )
)
order by game;

【讨论】:

【参考方案2】:

您还必须在顶部查询中进行分组,因为连接连接所有数据集。

【讨论】:

我不能做一个***组,因为我需要选择既不分组也不聚合的字段

以上是关于按列分组并选择具有多个最小值的行中的所有字段的主要内容,如果未能解决你的问题,请参考以下文章

如何在表的一个字段中按最小值分组,保留同一行中的所有值?

SQL查询以选择具有最小值的不同行

从具有不同值的行中选择所有值

如何在 MySQL 中选择字段具有最小值的数据?

MYSQL如何选择字段具有最小值的数据

应用 group_by 并汇总数据,同时保留所有列的信息