使用{Rows Preceding}来移动平均sql

时间:2015-09-15 18:49:26

标签: sql sql-server aggregate window-functions moving-average

在下面的代码中,我试图计算每个月的移动平均值与过去6个月的比较,但是SQL排除了分母中为空的行的平均值。

例如: -

让我们说9月份的avg(count(*))是4,3月到8月的值是0.在我的代码中,SQL占用4/1但我需要它包括前几个月,即使它们没有价值观(4/6)。

select [Name],[Report Month]
,avg(count(*))  over (partition by [Name]
                              order by [Report Month]
                              ROWS 5 PRECEDING)
FROM dbo.Sample
group by [Name],[Report Month]

根据Tab的建议。我尝试创建一个月份表,与dbo.sample保持联系,我不熟悉创建月份表,因此我使用了在线资源,以下是代码(我使用SQLServer2014,它在资源中说,代码是2000)

CREATE TABLE CalendarMonths (
  date DATETIME,
  PRIMARY KEY (date)
)

DECLARE
  @basedate DATETIME,
  @offset   INT
SELECT
  @basedate = '01 Jan 2000',
  @offset = 1

WHILE (@offset < 2048)
BEGIN
  INSERT INTO CalendarMonths SELECT DATEADD(MONTH, @offset, date) FROM CalendarMonths
  SELECT @offset = @offset + @offset
END

非常感谢你的帮助!...提前谢谢你。

最佳,

1 个答案:

答案 0 :(得分:2)

由于您从空表中执行INSERT ... SELECT,因此有0行受到影响。

如果你替换它应该有用:

 INSERT INTO CalendarMonths SELECT DATEADD(MONTH, @offset, date) FROM CalendarMonths
 SELECT @offset = @offset + @offset

用这个:

INSERT INTO CalendarMonths SELECT DATEADD(MONTH, @offset, @basedate)
SET @offset = @offset + 1

然后只加入月份和年份的月份表,如下所示:

select [Name],cm.[date] AS ReportMonth
,avg(count(*))  over (partition by [Name]
                              order by cm.[date]
                              ROWS 5 PRECEDING)
FROM dbo.Sample s
RIGHT OUTER JOIN CalendarMonths cm
  ON MONTH(s.[Report Month])=MONTH(cm.[date])
  AND YEAR(s.[Report Month])=YEAR(cm.[date])

group by [Name],cm.[date]