使用SQL Server2016。我有一个表:
Product Qty OrderDate
--------------------------
Toys 100 2018-10-01
Toys 100 2018-10-01
Books 30 2018-10-01
Toys 150 2018-10-02
Toys 50 2018-10-02
Toys 20 2018-10-02
Toys 110 2018-10-03
Toys 90 2018-10-04
Toys 200 2018-10-05
Toys 100 2018-10-05
Toys 30 2018-10-08
Toys 50 2018-10-09
,我想计算最近5天每种产品的平均数量。这个查询与我很接近:
SELECT
Product,
RowNumber,
OrderDate,
AVG(TotalQty) OVER (ORDER BY RowNumber DESC ROWS 5 PRECEDING) as RollingAvg
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY Product ORDER BY orderDate) AS RowNumber, Product, OrderDate, sum(Qty) as TotalQty
FROM Tbl
GROUP BY Product, OrderDate
) x
GROUP BY Product, RowNumber, OrderDate
内部查询正常工作,为我提供每个产品/日期对的总数。但是我的外部查询报告了一个问题:
Column 'x.TotalQty' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
我的OVER子句显然出了问题,因为当我删除那个时,我得到了一个有效的结果。
语法上有效的查询(做错了事):
SELECT
Product,
RowNumber,
OrderDate,
AVG(TotalQty) as RollingAvg
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY Product ORDER BY orderDate) AS RowNumber, Product, OrderDate, sum(Qty) as TotalQty
FROM Tbl
GROUP BY Product, OrderDate
) x
GROUP BY Product, RowNumber, OrderDate
任何帮助/指针都将不胜感激-我很亲密,但不能越过最后的关卡!
答案 0 :(得分:1)
我想你想要
SELECT Product, RowNumber, OrderDate,
AVG(TotalQty) OVER (ORDER BY RowNumber DESC ROWS 5 PRECEDING) as RollingAvg
FROM (SELECT ROW_NUMBER() OVER (PARTITION BY Product ORDER BY orderDate) AS RowNumber,
Product, OrderDate, sum(Qty) as TotalQty
FROM Tbl
GROUP BY Product, OrderDate
) x;
也就是说,不需要外部聚合,因为AVG()
被用作窗口函数,而不是聚合函数。
您应该能够在没有子查询的情况下执行此操作:
SELECT ROW_NUMBER() OVER (PARTITION BY Product ORDER BY orderDate) AS RowNumber,
Product, OrderDate, sum(Qty) as TotalQty,
AVG(SUM(Qty)) OVER (PARTITION BY Product ORDER BY orderDate ROWS BETWEEN 4 PRECEDING AND CURRENT ROW) as avg_5
FROM Tbl
GROUP BY Product, OrderDate;
请注意,这会将“最后五天”解释为当前日期加上前四天。您的版本平均需要六天的时间。