Почему оконные функции требуют моего агрегированного столбца в группе - PullRequest
0 голосов
/ 02 марта 2020

Я довольно много работал с оконными функциями, но не думаю, что достаточно хорошо понимаю, как они работают, чтобы ответить, почему они ведут себя так, как они.

Для запроса, над которым я работал (ниже), почему я должен взять свое агрегированное поле и добавить его в группу? (Во второй половине моего запроса ниже я не могу получить результат, если я не включил «События» во вторую группу):

With Data as (
Select 
  CohortDate as month
  ,datediff(week,CohortDate,EventDate)  as EventAge
  ,count(distinct case when EventDate is not null then GUID end) as Events
From MyTable
where month >= [getdate():month] - interval '12 months'
group by 1, 2
order by 1, 2
  )

Select 
  month
  ,EventAge
  ,sum(Events) over (partition by month order by SubAge asc rows between unbounded preceding and current row) as TotEvents
from data
group by 1, 2, Events
order by 1, 2 

Я столкнулся с этим достаточно, чтобы я просто принял это как должное, но очень хотелось бы еще немного цвета, почему это необходимо. Есть ли способ, которым я должен форматировать их по-разному, чтобы избежать этого (несколько не интуитивного) требования?

Спасибо за тонну!

1 Ответ

0 голосов
/ 02 марта 2020

То, что вы ищете, предположительно является накопительной суммой. Это было бы:

select month, EventAge,
       sum(sum(Events)) over (partition by month
                              order by SubAge asc 
                              rows between unbounded preceding and current row
                             ) as TotEvents
from data
group by 1, 2
order by 1, 2 ;

Почему? Это может быть немного сложно объяснить. Возможно, если вы увидите эквивалентную версию с подзапросом, она будет более понятной:

select me.*
       sum(sum_events) over (partition by month
                             order by SubAge asc 
                             rows between unbounded preceding and current row
                            ) as TotEvents
from (select month, EventAge, sum(events) as sum_events
      from data
      group by 1, 2
     ) me
order by 1, 2 ;

Это в значительной степени сокращение для запроса. Оконная функция оценивается после агрегации. Вы хотите суммировать СУММУ событий после агрегации. Следовательно, вам нужно sum(sum(events)). После агрегации events больше не доступен.

Вложение функций агрегации поначалу неудобно - по крайней мере, для меня. Когда я впервые начал использовать оконные функции, я сначала потратил несколько дней на написание запросов агрегации с использованием подзапросов, а затем переписывал их без подзапросов. Быстро я привык писать их без подзапросов.

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