SQL 中的 MIN 函数未按预期工作

MIN function in SQL not working as expected

我有一个 table 列出了游戏的玩家以及他们在游戏中的等级变化历史(初级、中级、高级、精英、专业)。我正在尝试构建一个查询,该查询将准确识别 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 年达到高级水平并且现在已经达到更高水平的人level- 我不想包括这些人,这就是我在日期中使用 MIN 的原因。

例如,它正确地拉入了玩家 1 和 2,他们都在 1 月 2 日达到了高级水平,而玩家 4 在跳过高级水平(直接从中级到精英)后,在 1 月 4 日达到了精英水平.但它也拉入了 Player 3,他在 2020 年 12 月 30 日达到高级,然后在 1 月 10 日达到精英 - 我不希望玩家 3 被包括在内,因为他们在 2021 年之前首次达到高级。我怎样才能得到我的查询排除这样的人?

玩家 3 的两个结果...一个是高级的,一个是精英的,因为您按 NewRank 分组。玩家 3 达到高级的那个被你的 WHERE t.first_time_adv > '1/1/2021' 从结果集中删除,精英通过。我建议尝试将 FILTEROVERMIN().

一起使用

您的内部查询结果包括如下内容:

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)

这是因为您在对 IDNewRank 进行分组时得到了 MIN。您想要 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
;

之前您是在为任何 rank IN ('Advanced', 'Elite', 'Pro') 找到 MIN(EffectiveDate)...现在您真正找到的是 EffectiveDate 当玩家达到 'Advanced' 时。