Роллинг Агрегация - PullRequest
       14

Роллинг Агрегация

1 голос
/ 26 февраля 2020

Я пытаюсь написать программу на SQL Сервере, который агрегирует на основе скользящих дат.

Возьмите это ниже

Acc Dte     Amount
1   1/1/20    100
1   1/3/20    200
1   1/8/20    100
1   1/8/20     75
2   1/1/20     50
2   1/2/20    100
2   1/3/20     75
2   1/3/20    125
3   1/3/20    100
3   1/6/20     75
3   1/8/20     75
3   1/10/20   200
3   1/10/20   150

Итак, цель в том, чтобы я хотел найти среднее и количество записей и дат для каждой учетной записи до анализа записи. Мне также нужно суммировать записи на основе даты. На основании вышеизложенного это будет выглядеть следующим образом ...

Acc  Dte    Num_of_dates Avg_Amount_per_day Current_Amount
1    1/3/20            1              100              200
1    1/8/20            2              150              175
2    1/2/20            1               50              100
2    1/3/20            2               75              200
3    1/6/20            1              100               75
3    1/8/20            2               83.3             75
3    1/10/20           3               83.3            350

Цель состоит в том, чтобы создать z-счет, сравнивающий номера счетов за текущий день с счета в среднем за день. Но нам также нужно получить как минимум 10 дней исторических данных для каждой учетной записи.

Прямо сейчас мой код выглядит так и не работает

select Account, 
       Dte, 
       (select sum(case when Cast(EventTimestamp as DATE) < Dte then 1 else 0 end) Num_of_Date,
       (select (case when Cast(EventTimestamp as DATE) < Dte then sum(Amount) else 0 end) t_amount
from Data
group by Account, Dte

Есть идеи? Спасибо

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

Ваш пример данных и описания предлагают:

select acc, dte,
       count(*) as num_on_day,
       sum(amount) as sum_on_day,
       avg(sum(amount)) over (partition by acc order by date_num range between unbounded preceding and 1 preceding) as avg_previous
from t cross join
     (values (datediff(day, '1900-01-01', dte))) v(date_num)
group by acc, dte;

Я не уверен, почему вы не включаете первую дату для каждого acc.

1 голос
/ 27 февраля 2020

Вы можете использовать оконные функции с правильным предложением rows. На этот раз нам пригодится distinct:

select distinct
    acc,
    dte,
    count(*) over(
        partition by acc
        order by dte
        rows between unbounded preceding and 1 preceding
    ) num_of_dates,
    avg(1.0 * amount) over(
        partition by acc
        order by dte
        rows between unbounded preceding and 1 preceding
    ) avg_amount_per_day,
    sum(amount) over(partition by acc, dte) current_amount
from mytable

Если вам нужна только одна запись на дату и учетную запись, как показано в примере данных, вы можете вложить запрос и использовать row_number() - в Отсутствие очевидного столбца для определения порядка сортировки, я полагался на совокупный счет:

select acc, dte, num_of_dates, avg_amount_per_day, current_amount
from (
    select 
        t.*, 
        row_number() over(partition by acc, dte order by num_of_dates) rn
    from (
        select
            acc,
            dte,
            count(*) over(
                partition by acc 
                order by dte
                rows between unbounded preceding and 1 preceding
            ) num_of_dates,
            avg(1.0 * amount) over(
                partition by acc 
                order by dte
                rows between unbounded preceding and 1 preceding
            ) avg_amount_per_day,
            sum(amount) over(partition by acc, dte) current_amount
        from mytable
    ) t
) t
where rn = 1 and avg_amount_per_day is not null

Демонстрация на DB Fiddlde :

acc | dte        | num_of_dates | avg_amount_per_day | current_amount
--: | :--------- | -----------: | :----------------- | -------------:
  1 | 2020-01-03 |            1 | 100.000000         |            200
  1 | 2020-01-08 |            2 | 150.000000         |            175
  2 | 2020-01-02 |            1 | 50.000000          |            100
  2 | 2020-01-03 |            2 | 75.000000          |            200
  3 | 2020-01-06 |            1 | 100.000000         |             75
  3 | 2020-01-08 |            2 | 87.500000          |             75
  3 | 2020-01-10 |            3 | 83.333333          |            350
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...