如何根据两个字段的最大值 select 记录作为第三个字段的子集?

How to select records based on max value of two fields as a subset of third field?

给出以下简单的 table:

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

我想构建一个查询,为每个 match_op_id 的单个记录(无论是哪个记录)选择 match_op_idbookie_idp1 字段] 来自每个 bookie_id 的最大值 version,然后是最大值 p1。所以从上面我会得到输出:

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

从另一个问题的答案我得到了:

SELECT o1.match_op_id, o1.bookie_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

但是,我不知道如何通过 bookie_id 实现最大值 version。任何帮助将不胜感激。


编辑:

要解决评论中提出的问题...对于每个 match_op_id 我正在寻找查询以查找 bookie_id 的最高 version 然后 return最高p1。因此,在上面的示例中,match_op_id“2”然后 bookie_id“1”的最大值 version 为“1”,p1 为“5”。 bookie_id“2”的最大值 version 为“2”,p1 为“4”。因此,查询应该 return bookie_id“1”,p1 为“5”。

SELECT DISTINCT match_op_id, bookie_id, max_version, max_p1
FROM (
SELECT distinct st1.match_op_id match_op_id, st2.bookie_id, st2.max_version, st3.max_p1
        FROM SIMPLE_table st1
        JOIN ( -- version
        SELECT match_op_id, bookie_id, MAX(`version`) max_version FROM simple_table GROUP BY match_op_id, bookie_id) st2
        ON st1.match_op_id = st2.match_op_id
        JOIN ( -- p1
        SELECT match_op_id, bookie_id, `version`, MAX(p1) max_p1 FROM simple_table GROUP BY match_op_id, bookie_id, `version`) st3
        ON st2.max_version=st3.`version` AND st2.bookie_id=st3.bookie_id AND st1.match_op_id=st3.match_op_id) all_
GROUP BY max_version HAVING MAX(max_p1)

给出:

"match_op_id"   "bookie_id" "max_version"   "max_p1"
"2"             "1"         "1"             "5"
"1"             "2"         "2"             "4"

你觉得这样对吗?

SQL

WITH max_versions AS
(SELECT match_op_id, bookie_id, MAX(version) AS version
 FROM tbl
 GROUP BY match_op_id, bookie_id),
mv_full AS
(SELECT t.match_op_id, t.bookie_id, t.p1
 FROM max_versions mv
 JOIN tbl t
   ON mv.match_op_id = t.match_op_id
  AND mv.bookie_id = t.bookie_id
  AND mv.version = t.version),
max_p1s AS
(SELECT match_op_id, MAX(p1) AS p1
 FROM mv_full
 GROUP BY match_op_id)
SELECT mf.*
FROM mv_full mf
JOIN max_p1s mp
ON mp.match_op_id = mf.match_op_id
AND mp.p1 = mf.p1

演示

DB Fiddle Demo

您可以使用 ROW_NUMBER() window 函数两次。
首先使用它为 match_op_idbookie_id 的每个组合获取最大 version 的行,然后对于返回的行使用它为每个 match_op_id 获取行最大 p1:

SELECT match_op_id, bookie_id, p1
FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY match_op_id ORDER BY p1 DESC) rn2
  FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY match_op_id, bookie_id ORDER BY version DESC) rn1
    FROM odds_op
  ) t  
  WHERE rn1 = 1
) t
WHERE rn2 = 1

ROW_NUMBER()FIRST_VALUE:

SELECT DISTINCT match_op_id, 
       FIRST_VALUE(bookie_id) OVER (PARTITION BY match_op_id ORDER BY p1 DESC) bookie_id, 
       MAX(p1) OVER (PARTITION BY match_op_id) p1
FROM (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY match_op_id, bookie_id ORDER BY version DESC) rn
  FROM odds_op
) t  
WHERE rn = 1

参见demo
结果:

match_op_id bookie_id p1
1 2 4
2 1 5