如何查找列的日期和指定值的运行总计?

Posted

技术标签:

【中文标题】如何查找列的日期和指定值的运行总计?【英文标题】:How to find the running total over dates and specified value of a column? 【发布时间】:2020-12-18 21:51:59 【问题描述】:

下面是我的数据集的样子: [1]:https://i.stack.imgur.com/v6r9J.png

CustNumber  Status  Date    Running Total of Days
C100    IN  10/10/2019  
C100    OUT 10/11/2019  1
C100    IN  10/12/2019  
C100    OUT 10/13/2019  1
C100    IN  10/16/2019  
C100    OUT 10/17/2019  1
C100    IN  4/23/2020   
C100    OUT 4/27/2020   
C100    OUT 4/28/2020   
C100    OUT 4/28/2020   5
C100    IN  10/13/2020  
C100    OUT 10/19/2020  6

每次“状态”列的值从 IN 变为 OUT 时,我想计算总天数列。 2019 年 10 月 10 日,该值为 IN。 2019 年 10 月 11 日,该值为 OUT。所以总和应该是 1。

对于同一位客户,2019 年 4 月 23 日,该值为 IN。在 04/28 上,该值再次为 OUT。所以运行总数应该是 5,因为它处于“IN”状态 5 天。

如何在 SQL 中实现这个查询?

【问题讨论】:

用您正在使用的数据库标记您的问题。此外,将结果显示为问题中的格式化表格 【参考方案1】:

我会将此作为一个差距和孤岛问题来解决。每次看到“IN”状态时都会启动一个岛:我们可以使用“IN”状态的窗口计数来识别这些“相邻”记录组,然后进行日期算术:

select t.*,
    date - min(date) over(partition by grp) as running_total_of_days
from (
    select t.*,
        sum(case when status = 'IN' then 1 else 0 end) 
            over(partition by custnumber order by date) as grp
    from mytable t
) t

计算日期差异的实际语法因数据库而异 - 您没有告诉您使用的是哪一个。以上适用于支持直接减去日期的数据库(例如 Oracle 或 Postgres);其他数据库具有相同的语法或功能。

这会将运行总计放在每一行上。如果您只想在每组的最后一个“OUT”行中使用它,则可以使用 case 表达式:

select t.*,
    case when status = 'OUT' and row_number() over(partition by grp order by date desc) = 1
        then date - min(date) over(partition by grp) 
    end as running_total_of_days
from (
    select t.*,
        sum(case when status = 'IN' then 1 else 0 end) 
            over(partition by custnumber order by date) as grp
    from mytable t
) t

【讨论】:

谢谢。这很有帮助。:)

以上是关于如何查找列的日期和指定值的运行总计?的主要内容,如果未能解决你的问题,请参考以下文章

如何将一列的运行总计添加到 Access 查询?

在 Spark 数据集中创建具有运行总计的列

使用 JavaScript,如何在具有多个值的日期列的表中突出显示“今天”的每个日期

如何从日期中查找整个日期列的工作日

查找指定列的重复行[重复]

使用 foreach 循环添加每列的总和并在表格底部显示每个总计