Как получить скользящий различный счетчик каждого дня за последние три дня в Oracle SQL? - PullRequest
0 голосов
/ 21 октября 2018

Я много искал, но пока не нашел решения.позвольте мне объяснить мой вопрос на примере данных и желаемого результата.пример данных:

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-го, потому что у нас есть толькоУ Райана и Сары счет 2 (также потому, что у нас нет других записей до 21-го);для 22-го Энди и Питер добавляются в отдельный список, так что это 4. для 23-го, новый клиент не добавляется, поэтому это будет 4. для 24-го, однако, как мы должны учитывать только последние 3 дня (согласно бизнес-логике),мы должны взять только 24-е, 23-е и 22-е место;так что отличными покупателями будут Сара, Энди и Питер.таким образом, счет равен 3.

Я полагаю, что это называется прогрессивным счетом, или счетчиком движений, или счетом по убыванию.но я не смог реализовать это в Oracle 11g SQL.Очевидно, это легко с помощью программирования на PL-SQL (Stored-Процедура / Функция).но, желательно, мне интересно, сможем ли мы получить это одним запросом SQL.

1 Ответ

0 голосов
/ 21 октября 2018

То, что вам нужно, это:

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;

Это должно иметь разумную производительность для небольшого числа дат.По мере увеличения числа дат производительность будет линейно снижаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...