让我们说我有一个表signups
的格式为:
| date | sign_ups |
|------------|----------|
| 2018-01-01 | 34 |
| 2018-01-02 | 23 |
| 2018-01-03 | 2 |
| ... | ... |
我现在想要写一个查询来计算前述7天平均注册等的,即对于给定的一天,平均其注册等的和符号起坐为前六天值。此blog post提供了这种解决方案:
select
date,
avg(sign_ups)
over (order by date asc
rows between 6 preceding and current row) as avg,
from signups
我不喜欢使用SQL的BETWEEN
,所以我写此溶液代替:
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
只是想确认两者是等价的,如果有这个问题更简洁/更有效的解决方案。
答案 0 :(得分:3)
首先,假设你真的是:
on b.date <= a.date and
b.date > interval '7 days'
然后他们只是如果你有每个日期只有一行等价的。
您的版本有很大不同-您在join
中的日期之后,但在Windows函数中的日期之前获取值。你必须在一种情况下,并在其他一些未知数量的8个值。但我得到这个问题的要点。
在窗口功能版本很多很多,很多,很多在自连接优选的。从性能和可理解性的角度来看,这简直是更好的。而且,正如您的代码充分说明的那样,Windows版本使表达您的实际意图变得更加容易。
答案 1 :(得分:2)
两个查询是不等效的:
1)作为回答@GordonLinoff,第一查询返回一样多条记录,因为有在表中,同时通过日期第二聚集体。为了使结果相同,每个日期应该只有一行
2)该:
rows between 6 preceding and current row
不等同于:
a.date <= b.date + interval '7 days'
首先,如由Dnoeth评论,所述第二形式是将平均当前的日期和过去7天,其表示的8天总计强>
此外,第二个表单将在最近N天内记录帐户记录,并且还会记录当前日期之后的所有记录。
您需要更改该子句以为日期范围添加上限,例如:
a.date <= b.date + interval '6 days' AND a.date >= b.date
这基本上模拟BETWEEN
...并且还可以拼写:
b.date BETEWEEN a.date - interval '6 days' AND a.date