SQL中的滚动平均值,而不使用中间值

SQL中的滚动平均值,而不使用中间值,sql,date,select,group-by,window-functions,Sql,Date,Select,Group By,Window Functions,假设我有一个表格,其注册格式如下: | date | sign_ups | |------------|----------| | 2018-01-01 | 34 | | 2018-01-02 | 23 | | 2018-01-03 | 2 | | ... | ... | 现在我想写一个查询来计算前7天的平均注册数,即给定一天的平均注册数和前6天的注册值。这提供了以下解决方案: select date, avg(

假设我有一个表格,其注册格式如下:

| date       | sign_ups |
|------------|----------|
| 2018-01-01 | 34       |
| 2018-01-02 | 23       |
| 2018-01-03 | 2        |
| ...        | ...      |
现在我想写一个查询来计算前7天的平均注册数,即给定一天的平均注册数和前6天的注册值。这提供了以下解决方案:

select
  date,
  avg(sign_ups) 
    over (order by date asc
          rows between 6 preceding and current row) as avg,
from signups
我不喜欢在两者之间使用SQL,因此我编写了以下解决方案:

SELECT 
  a.date, 
  AVG(b.sign_ups)
FROM 
  signups a 
JOIN 
  signups b ON a.date <= b.date + interval '7 days'
GROUP BY 
  a.date

只是想确认这两者是等价的,以及是否有更简洁/更有效的解决方案

首先,假设你的意思是:

on b.date <= a.date and
   b.date > interval '7 days'
那么,只有在每个日期只有一行的情况下,它们才是等价的

您的版本完全不同-您在联接中的日期之后但在windows函数中的日期之前获取值。一种情况下有8个值,另一种情况下有一些未知数。但我明白了问题的要点


窗口函数版本比自联接更受欢迎。从性能和可理解性的角度来看,这简直更好。而且,正如您的代码充分展示的那样,windows版本更容易表达您的实际意图。

首先,假设您的真正意思是:

on b.date <= a.date and
   b.date > interval '7 days'
那么,只有在每个日期只有一行的情况下,它们才是等价的

您的版本完全不同-您在联接中的日期之后但在windows函数中的日期之前获取值。一种情况下有8个值,另一种情况下有一些未知数。但我明白了问题的要点


窗口函数版本比自联接更受欢迎。从性能和可理解性的角度来看,这简直更好。而且,正如您的代码充分展示的那样,windows版本更容易表达您的实际意图。

这两个查询并不等价:

1正如@GordonLinoff所回答的,第一个查询返回的记录与表中的记录一样多,而第二个查询按日期进行聚合。为了使结果相同,每个日期应该只有一行

2这是:

rows between 6 preceding and current row
不等同于:

a.date <= b.date + interval '7 days'

这两个查询并不等同:

1正如@GordonLinoff所回答的,第一个查询返回的记录与表中的记录一样多,而第二个查询按日期进行聚合。为了使结果相同,每个日期应该只有一行

2这是:

rows between 6 preceding and current row
不等同于:

a.date <= b.date + interval '7 days'

你不喜欢中间的????你不应该从语言语法中挑选朋友。它起作用了。它能有效地完成工作。你还想要什么?为什么不直接运行这两个程序并比较结果呢?很容易发现第二个返回完全不同的东西。你不喜欢中间????你不应该从语言语法中挑选朋友。它起作用了。它能有效地完成工作。你还想要什么?为什么不直接运行这两个程序并比较结果呢?很容易发现第二个返回了完全不同的结果。即使在重写之后,它的平均时间仍然是8天,而不是7天:-@dnoeth:啊,是的,你是对的,我没有注意到这一点。。。我更新了我的答案:即使在重写之后,它的平均时间仍然是8天而不是7天:-@dnoeth:啊,是的,你是对的,我没有注意到这一点。。。我更新了我的答案: