如何根据两个字段的最大值选择记录?

鉴于以下简单表:

+-----+-------------+---------+----+
| id_ | match_op_id | version | p1 |
+-----+-------------+---------+----+
|   1 |           1 |       1 |  1 |
|   2 |           1 |       1 |  5 |
|   3 |           1 |       2 |  3 |
|   4 |           1 |       2 |  4 |
|   5 |           2 |       1 |  1 |
|   6 |           2 |       1 |  5 |
|   7 |           2 |       2 |  3 |
|   8 |           2 |       2 |  4 |
|   9 |           2 |       2 |  4 |
+-----+-------------+---------+----+

我想构建一个查询,从 max和 max 中为每个记录选择match_op_idp1字段(与哪个无关)。所以从上面我会得到输出:match_op_idversionp1

+-------------+----+
| match_op_id | p1 |
+-------------+----+
|           1 |  4 |
|           2 |  4 |
+-------------+----+

在 SO 上的一些帖子之后,我构建了一个查询,该查询选择该p1字段为最大值的所有记录:

SELECT 
    odds_op.match_op_id, odds_op.p1
FROM
    odds_op,
    (SELECT 
        match_op_id, MAX(p1) AS p1
    FROM
        odds_op
    GROUP BY match_op_id) AS max_p1
WHERE
    odds_op.match_op_id = max_p1.match_op_id
        AND odds_op.p1 = max_p1.p1

我现在不知道如何确保我只p1从最大值中选择最大值version。我认为这可能是一个嵌套的子查询,但我无法弄清楚。我也知道我会遇到一些分组问题,这样我就不会在每个match_op_id. 任何帮助将非常感激。

回答

对于 MySql 8.0+,您可以使用FIRST_VALUE()窗口函数来完成:

SELECT DISTINCT match_op_id,
       FIRST_VALUE(p1) OVER (PARTITION BY match_op_id ORDER BY version DESC, p1 DESC) p1
FROM odds_op

对于以前的版本,使用NOT EXISTS过滤表,以便只返回具有最大值version的行,match_op_id然后聚合以获得最大值p1

SELECT o1.match_op_id, MAX(o1.p1) p1
FROM odds_op o1
WHERE NOT EXISTS (
  SELECT 1 
  FROM odds_op o2 
  WHERE o2.match_op_id = o1.match_op_id AND o2.version > o1.version
)
GROUP BY o1.match_op_id

或者在WHERE子句中使用相关子查询:

SELECT o1.match_op_id, MAX(o1.p1) p1
FROM odds_op o1
WHERE o1.version = (SELECT MAX(o2.version) FROM odds_op o2 WHERE o2.match_op_id = o1.match_op_id)
GROUP BY o1.match_op_id

请参阅演示。
结果:

match_op_id p1
1 4
2 4

以上是如何根据两个字段的最大值选择记录?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>