Как получить 'COUNT DISTINCT' над движущимся окном - PullRequest
0 голосов
/ 17 декабря 2018

Я работаю над запросом для вычисления отдельных пользователей определенных функций приложения в движущемся окне.Итак, если есть диапазон с 15 по 20 октября, я хочу, чтобы запрос проходил с 8 по 15 октября, с 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 голосов
/ 19 декабря 2018

Это не легко сделать эффективно.Счетчики DISTINCT не поддерживаются пошагово (если вы не идете по пути точных подсчетов DISTINCT, таких как HyperLogLog).

Кодирование в SQL легко, и попробуйте обычную индексацию и т. Д., Чтобы помочь.

Однако (возможно) невозможно кодировать с помощью функций OLAP ... не в последнюю очередь потому, что вы можете использовать ДИАПАЗОН МЕЖДУ SUM(), COUNT(), MAX() и т. Д., Но не 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
...