Row_Number() OVER PARTITION BY 基于列中的值

Posted

技术标签:

【中文标题】Row_Number() OVER PARTITION BY 基于列中的值【英文标题】:Row_Number() OVER PARTITION BY based on a value in column 【发布时间】:2020-03-12 15:36:51 【问题描述】:

表名:L

我目前正在使用一个数据集,旨在提供有关客户支持案例的见解。在上面的示例中,您可以看到案例 123376 从重新打开到已回答的进度。

当我使用分区函数ROW_NUMBER() OVER (PARTITION BY L.CaseNumber, L.[Status], L.NextDate ORDER BY L.[Date] ASC) 时,我得到了Row_Number,如上所述。但是,一旦案例状态得到回答并且下一个日期是NULL,那么我想删除之后那个案例的行,这意味着我只想保留第一行作为下一个日期NULL(在单个案件编号)并删除其他案件。有没有办法让行号超过分区,以便结果看起来像这样或任何其他方法?

【问题讨论】:

Status 从您的 PARTITION BY 子句中删除。 请不要发布数据或代码的图片。可以复制和粘贴纯文本,以便其他用户可以为您提供更好的答案。 【参考方案1】:

我想知道以下表达式是否可以满足您的要求 - 至少,我认为它应该适用于您的示例数据:

DENSE_RANK() OVER (
    PARTITION BY L.CaseNumber, L.[Status], L.NextDate 
    ORDER BY COALESCE(l.NexDate, L.[Date])
) 

【讨论】:

感谢您的回复。问题是这也将状态为“重新打开”的前 3 行排名为 1、2、3,我需要将这些行保留在表中。所以,我需要一个想法,将排名或行号应用于下一个日期为 NULL 的案例行 @SalmanTahir:我明白。我稍微修改了答案,现在更好了吗? 有趣的解决方案!完美运行。非常感谢【参考方案2】:

我认为您必须考虑 [下一个日期] 可以变化的情况? 下面是一个窗口查询,它有助于从 [Next Date] 中删除所有连续的 null,并且永远不会受到 [Next Date] 模式的影响。

with more as (
    select 
        L.*,
        case when
        LAG(L.[Next Date])
        over (
            partition by L.[CaseNumber]
            order by L.[Date], L.[Next Date]
        )
        is null then 1 end as [Last Is Null]
    from L
)
select * from more where more.[Next Date] is null and more.[Last Is Null] = 1

注意:只需将最后一个 select * 变成 delete 即可执行删除。

【讨论】:

我稍微调整了一下:(CASE WHEN LAG(M.[NextDate]) OVER (PARTITION BY M.[CaseNumber] ORDER BY M.[CalendarDate], M.[NextDate]) IS NULL AND M.NextDate IS NULL AND M.[Status Change]='Answered' THEN 1 END) AS [Last Is Null] 这确保焦点仅在 Status = Answered 上。我们还可以获取第一行已回答并删除其他。此外,将 M.[Next Date] IS NULL 带入 CASE WHEN 函数是个好主意。这样,每个案例编号的 LAG 的第一行默认不会标记为 NULL。再次感谢!

以上是关于Row_Number() OVER PARTITION BY 基于列中的值的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 批量删除重复记录

SQL Server 批量删除重复记录

Spark2 DataFrame数据框常用操作之分析函数--排名函数row_number,rank,dense_rank,percent_rank

sql apply查询应用

sql apply查询应用

Oracle中ROW_NUMBER() OVER()函数用法