如何在Oracle SQL中拥有过去三天每天的滚动非重复计数?



我搜索了很多,但还没有找到解决方案。 让我通过示例数据和我想要的输出来解释我的问题。 示例数据:

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 日,安迪和彼得被添加到不同的列表中,所以它是 4。 对于 23 日,没有添加新客户,因此为 4。 但是,对于 24 日,因为我们只应该考虑过去 3 天(根据业务逻辑(, 我们应该只拿第24、23和22名;所以不同的客户将是莎拉、安迪和彼得。所以计数是 3。

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

你似乎想要的是:

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;

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

最新更新