【问题标题】:Getting unique record based on max conditions including null values根据包括空值在内的最大条件获取唯一记录
【发布时间】:2021-09-05 17:05:04
【问题描述】:

我需要取回一个玩家(仅限 A 级玩家)最近获胜日期的记录(有些获胜日期是空的,但我们需要将它们包括在内),但只选择他们最近游戏会话的最后一个位置。所以基本上按照这个顺序:获取他们的最大 win_date(如果为 null,仍然包括它们)> 从那里获取他们的最大位置 > 然后从那里只选择他们的最大 game_session_id。

桌面玩家:

Badge_No    Name     Game_Session_ID    Place    Win_Date    Rank
565         Barry    012550             4        6/17/2021    A
565         Barry    003521             2        3/04/2021    A
565         Barry    003521             3        3/04/2021    A
565         Barry    003521             4        3/04/2021    A
565         Barry    003521             5        3/04/2021    A
565         Barry    095945             1        6/17/2021    A
101         Lee      065411             1                     A
018         Jess     001561             1        5/23/2020    A
018         Jess     002075             1        5/23/2020    A         
209         Linda    026541             2        5/06/2021    A
728         Perry    000940             1        1/23/2021    B

预期输出:

Badge_No    Name     Game_Session_ID    Place    Win_Date    Rank
565         Barry    012550             4        6/17/2021    A
101         Lee      065411             1                     A
018         Jess     002075             1        5/23/2020    A 
209         Linda    026541             2        5/06/2021    A

我的(错误的)代码:

select distinct badge_no, 
       name, max(game_session_id) game_session_id, 
       max(place) place, max(win_date) win_date, rank
from players p
where not exists 
    (select 'x' from players p2 
      where p2.badge_no = p.badge_no and p.rank = 'B')
group by badge_no, name, rank

【问题讨论】:

    标签: sql oracle subquery max dense-rank


    【解决方案1】:

    ROW_NUMBER 与适当的分区一起使用:

    WITH cte AS (
        SELECT p.*, ROW_NUMBER() OVER (PARTITION BY Badge_No
                                       ORDER BY Win_Date DESC, Place DESC, Game_Session_ID DESC) rn
        FROM players p
        WHERE "Rank" = 'A'
    )
    
    SELECT Badge_No, Name, Game_Session_ID, Place, Win_Date, "Rank"
    FROM cte
    WHERE rn = 1;
    

    【讨论】:

      【解决方案2】:
      select badge_no, name,
             max(game_session_id) keep (dense_rank last
                             order by win_date nulls first, place) as game_session_id,
             max(place) keep (dense_rank last order by win_date nulls first) as place,
             max(win_date) as win_date, rank
      from   players
      where  rank = 'A'
      group  by badge_no, name, rank
      ;
      

      如果您不熟悉 first / last 聚合函数(别担心,您不会孤单!),您可能需要快速查看文档以了解它的作用。

      【讨论】:

      • 由于某种原因,它不喜欢“first”这个词——也许语法是错误的......但我会阅读文档。谢谢!
      • Max game_session_id of max place at max win_date - 它们是链式的,所以它们都需要在 order by 部分中。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-13
      相关资源
      最近更新 更多