【问题标题】:Why Window Functions Require My Aggregated Column in Group为什么窗口函数需要我在组中的聚合列
【发布时间】:2020-03-02 18:34:11
【问题描述】:

我一直在使用大量窗口函数,但我认为我对它们的工作方式了解得不够多,无法回答为什么它们会以这种方式运行。

对于我正在处理的查询(如下),为什么我需要获取我的聚合字段并将其添加到 group by? (在下面我的查询的后半部分,如果我的第二组中不包含“事件”,我将无法产生结果)

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 

我已经遇到了足够多的问题,以至于我认为它是理所当然的,但我真的很喜欢更多颜色,以了解为什么需要它。有没有办法我应该以不同的方式格式化这些以避免这种(有点不直观)的要求?

非常感谢!

【问题讨论】:

  • 这是我发现的最相似的问题,但它似乎没有回答我提出的问题,因为我认为我已经包含了我分组的所有字段,而不是被要求添加在聚合字段中也是如此! stackoverflow.com/questions/19601948/…

标签: sql postgresql group-by window-functions cumulative-sum


【解决方案1】:

您要查找的内容大概是累积总和。那将是:

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(sum(events))。聚合后,events 不再可用。

聚合函数的嵌套一开始很尴尬——至少对我来说是这样。当我第一次开始使用窗口函数时,我想我首先花了几天时间使用子查询编写聚合查询,然后在没有子查询的情况下重写。很快,我习惯了在没有子查询的情况下编写它们。

【讨论】:

  • 谢谢@Gordon。我一直使用的结构是您在下面提到的子查询版本。我正在 (....) 上进行 sum([AggField1]),其中 [AggField1] = "Count(distinct ID) where condition is true"。我在我所做的和我在您的子查询版本中看到的最大区别是您没有在最外层查询中请求 group by。当我更新查询以将组删除 1,2 时,[sum_events] 它按预期工作。这有助于避免它。但仍然难以理解为什么会这样。哦,好吧,你的方式更好!
  • @djdoerr 。 . .因为窗口函数是在聚合之后进行评估的。 events 在聚合后不存在(你想要的),但 sum(events) 存在。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多