如何在移动窗口上获得“ COUNT DISTINCT”

时间:2018-12-17 18:43:17

标签: sql db2 window-functions

我正在处理一个查询,以计算移动窗口内应用程序特定功能的不同用户。因此,如果范围是10月15日至20日,我希望查询从10月8日至15日,10月9日至16日等开始,并获取每个功能的独立用户数。因此,对于每个日期,它应该有x行,其中x是要素数量。

到目前为止,我对以下查询有一个查询:

WITH V1(edate, code, total) AS
   (
     SELECT date, featurecode, 
    DENSE_RANK() OVER ( PARTITION BY (featurecode ORDER BY accountid ASC) + DENSE_RANK() OVER ( PARTITION BY featurecode ORDER By accountid DESC) - 1 

FROM....
 GROUP BY edate, featurecode, appcode, accountid
 HAVING appcode='sample' AND eventdate BETWEEN '15-10-2018' And '20-10-2018'
) 

Select distinct date, code, total
from V1
WHERE date between '2018-10-15' AND '2018-10-20'

这将为所有日期返回相同的一组值。有什么办法可以有效地做到这一点?顺便说一下,它是一个DB2数据库,但我也在寻找来自postgresql用户的见解。

Present result- All the totals are being repeated.

date        code                 total
10/15/2018   appname-feature1       123
10/15/2018   appname-feature2       234
10/15/2018   appname-feature3       321
10/16/2018   appname-feature1       123
10/16/2018   appname-feature2       234
10/16/2018   appname-feature3       321

Desired result.
date        code                 total
10/15/2018   appname-feature1       123
10/15/2018   appname-feature2       234
10/15/2018   appname-feature3       321
10/16/2018   appname-feature1       212
10/16/2018   appname-feature2       577
10/16/2018   appname-feature3       2345

1 个答案:

答案 0 :(得分:0)

要有效地做到这一点并不容易。 DISTINCT计数不可增量维护(除非您沿用不精确的DISTINCT计数,例如HyperLogLog)。

使用SQL编写代码很容易,并尝试使用通常的索引编制等来提供帮助。

但是,(可能)不可能使用OLAP函数进行编码。.尤其是因为您只能对SUM()COUNT()MAX()等使用RANGE BETWEEN,但是而不是RANK()或DENSE_RANK() ...,因此只需使用传统的相关关联子选择

首先提供一些数据

CREATE TABLE T(D DATE,F CHAR(1),A CHAR(1));
INSERT INTO T (VALUES
    ('2018-10-10','X','A')
,   ('2018-10-11','X','A')
,   ('2018-10-15','X','A')
,   ('2018-10-15','X','A')
,   ('2018-10-15','X','B')
,   ('2018-10-15','Y','A')
,   ('2018-10-16','X','C')
,   ('2018-10-18','X','A')
,   ('2018-10-21','X','B')
) 
;

现在简单选择

WITH B AS (
    SELECT DISTINCT D, F FROM T
)
SELECT D,F
,    (SELECT COUNT(DISTINCT A)
      FROM T
      WHERE T.F = B.F 
      AND T.D BETWEEN B.D - 3 DAYS AND B.D + 4 DAYS
      ) AS DISTINCT_A_MOVING_WEEK
FROM
    B
ORDER BY F,D
;

给予,例如

 D          F DISTINCT_A_MOVING_WEEK
 ---------- - ----------------------
 2018-10-10 X                      1
 2018-10-11 X                      2
 2018-10-15 X                      3
 2018-10-16 X                      3
 2018-10-18 X                      3
 2018-10-21 X                      2
 2018-10-15 Y                      1