如何在Oracle SQL中对过去三天的每天滚动滚动计数?

时间:2018-10-21 09:41:42

标签: sql oracle

我进行了很多搜索,但是找不到解决方案。让我通过示例数据和所需的输出来解释我的问题。 样本数据:

datetime           customer
----------         --------
2018-10-21 09:00   Ryan
2018-10-21 10:00   Sarah
2018-10-21 20:00   Sarah
2018-10-22 09:00   Peter
2018-10-22 10:00   Andy
2018-10-23 09:00   Sarah
2018-10-23 10:00   Peter
2018-10-24 10:00   Andy
2018-10-24 20:00   Andy

我想要的输出是相对于每天过去三天的独特客户数量:

trunc(datetime)   progressive count distinct customer
---------------   -----------------------------------
2018-10-21         2
2018-10-22         4
2018-10-23         4
2018-10-24         3

说明:对于21日,因为我们只有Ryan和Sarah,所以计数为2(也因为在21日之前我们没有其他记录);第22位,因此Andy和Peter被添加到了不重复列表中,因此第4位。第23位,没有添加任何新客户,因此第24位则为4.。但是,由于我们只应考虑过去3天(根据业务逻辑),我们应该只乘24、23和22;因此,不同的客户将是Sarah,Andy和Peter。因此计数为3。

我认为它称为累进计数,移动计数或汇总计数。但是我无法在Oracle 11g SQL中实现它。显然,使用PL-SQL编程(存储过程/函数)很容易。但是,最好是我想知道是否可以通过单个SQL查询来获得它。

1 个答案:

答案 0 :(得分:1)

您似乎想要的是:

select date,
       count(distinct customer) over (order by date rows between 2 preceding and current row)
from (select distinct trunc(datetime) as date, customer
      from t
     ) t
group by date;

但是,Oracle不支持带有count(distinct)的窗口框架。

一种蛮力的方法是相关子查询:

select date,
       (select count(distinct t2.customer)
        from t t2
        where t2.datetime >= t.date - 2
       ) as running_3
from (select distinct trunc(datetime) as date
      from t
     ) t;

这应该在少量日期中具有合理的性能。随着日期数量的增加,性能会线性下降。