我有一个表,列出了玩家的游戏和他们在游戏中的水平变化的历史(初学者,中级,高级,精英,专业)。我正在尝试构建一个查询,该查询将准确地识别那些在2021年第一次达到高级或更高级别的人(玩家可以跳过等级,所以我想知道他们达到高级、精英或职业水平的最早日期)。我目前正在使用以下查询:
SELECT *
FROM (
SELECT p."ID", ra."NewRank", MIN(ra."EffectiveDate") AS "first_time_adv"
FROM rankachievement ra
JOIN player p
ON ra."ID" = p."ID"
WHERE ra."NewRank" IN ('Advanced',
'Elite',
'Pro')
GROUP BY 1, 2) AS t
WHERE t."first_time_adv" > '1/1/2021'
ORDER BY 1 现在,这吸引了所有在2021年第一次达到先进水平的人,但也吸引了一些在2020年达到先进水平的人,现在已经达到了更高的水平--我不想把这些人包括在内,这就是为什么我用MIN作为日期的原因。
例如,这是正确的吸引球员1和2,谁都在1月2日高级,第4,谁跳过高级水平后在1月4日到达精英(直接从中级到精英)。但它也吸引了第3名球员,他在2020年12月30日达到了先进水平,然后在1月10日达到了精英--我不想让第3名球员被包括在内,因为他们在2021年之前第一次达到了高级水平。如何才能让我的查询排除这样的人?
发布于 2021-01-26 17:51:59
你得到了第三名球员的两个结果.一个是高级的,一个是精英,因为你是按NewRank分组的。玩家3到达高级的地方被你的WHERE t.first_time_adv > '1/1/2021'从结果集中移除,精英通过。我建议尝试在FILTER和OVER中使用MIN()。
来自内部查询的结果包括如下内容:
id | new_rank | MIN(EffectiveDate)
---+----------+-------------------
1 | advanced | the min date for this record (12/30/2020)
1 | elite | the min date for this record (01/10/2021)这是因为您在对MIN和ID进行分组时获得了NewRank。你想要MIN凌驾于那个球员的所有记录之上。如果您只按ID分组,您可能会得到您想要的行为,但这将要求您从SELECT子句中删除NewRank。
我怀疑你想要在你的最终结果集中的排名,所以尝试如下所示:
WITH data AS
(
SELECT p."ID"
, ra."NewRank"
, ra."EffectiveDate"
, MIN(ra."EffectiveDate")
FILTER (WHERE ra."NewRank" = 'Advanced')
OVER (PARTITION BY p."ID") AS "first_time_adv"
FROM rankachievement ra
JOIN player p ON ra."ID" = p."ID"
WHERE ra."NewRank" IN ('Advanced', 'Elite', 'Pro')
)
SELECT *
FROM data d
WHERE d."first_time_adv" > '1/1/2021'
ORDER BY 1
;之前你为任何一个MIN(EffectiveDate)找到了rank IN ('Advanced', 'Elite', 'Pro').现在,当玩家到达'Advanced'时,您将真正找到该'Advanced'。
https://stackoverflow.com/questions/65904853
复制相似问题