如何根据两个字段的最大值 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_id
、bookie_id
和 p1
字段] 来自每个 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
演示
您可以使用 ROW_NUMBER()
window 函数两次。
首先使用它为 match_op_id
和 bookie_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
给出以下简单的 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_id
、bookie_id
和 p1
字段] 来自每个 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
演示
您可以使用 ROW_NUMBER()
window 函数两次。
首先使用它为 match_op_id
和 bookie_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