列的值是接下来的4个值的总和 - SQL

时间:2015-07-29 13:42:12

标签: sql sql-server sql-server-2012

ITEM   LOCATION    QTY    WEEK 
A        X          30      1
A        X          35      2
A        X          40      3
A        X          0       4     
A        X          10      5 
A        X          19      6

我需要创建一个新的列,其计算类似于..

ITEM     LOCATION   QTY    WEEK   NEW_COLUMN
 A           X      30       1    AVG(WEEK2(qty)+WEEK3(qty)+WEEK4(qty)+WEEK5(qty))
 A           X      35       2    AVG(WEEK3(qty)+WEEK4(qty)+WEEK5(qty)+WEEK6(qty))

同样适用于所有行......

平均4周是固定的,它不会改变。 第一周将有接下来4周的平均值,即2,3,4和5 avg(35+40+0+10) 第二周将有接下来4周的平均值,即3,4,5和6 avg(40+0+10+19)

我试图根据周数来创建它们 Week 1-4 as 1 Week 5-8 as 2。 并试图做这个过程,但我得到了相同的平均每个桶,说1,2,3,4行项目的相同值..

6 个答案:

答案 0 :(得分:3)

使用限制Weeks在您的范围内的条款加入同一个表应该有效。您必须确定过去几周的正确答案(之后不会有4周)以及COALESCE正确答案或INNER JOIN出来的答案。

 SELECT T.Item, T.Location, T.Week, AVG(N.Qty) as New_Column
 FROM Table T
 LEFT OUTER JOIN Table N ON
     T.Item = N.Item
     AND T.Location = N.Location
     AND N.Week BETWEEN (T.Week + 1) AND (T.Week + 4)
 GROUP BY T.Item, T.Location, T.Week

答案 1 :(得分:2)

您可以自行加入同一张桌子4次:

select t0.item, t0.location, t0.qty, t0.week,
    (t1.qty + t2.qty + t3.qty + t4.qty) / 4.0
from [table] t0
left join [table] t1 on t0.item = t1.item and t0.location = t1.location 
    and t1.week = t0.week + 1
left join [table] t2 on t0.item = t2.item and t0.location = t2.location 
    and t2.week = t0.week + 2
left join [table] t3 on t0.item = t3.item and t0.location = t3.location 
    and t3.week = t0.week + 3
left join [table] t4 on t0.item = t4.item and t0.location = t4.location 
    and t4.week = t0.week + 4

如果您有更好的密钥可用于表格,则可以简化这些联接。

答案 2 :(得分:2)

其他一些答案工作正常,但2012年应该很容易:

SELECT *,New_Column = (SUM(Qty) OVER(ORDER BY Week ROWS BETWEEN 1 FOLLOWING AND 5 FOLLOWING)*1.0)/4
FROM Table1

演示:SQL Fiddle

如果是itemlocation,那么只需添加PARTITION BY

SELECT *,New_Column = (SUM(Qty) OVER(PARTITION BY Item, Location ORDER BY Week ROWS BETWEEN 1 FOLLOWING AND 5 FOLLOWING)*1.0)/4
FROM Table1

要过滤掉不具有4条后续记录的记录,您可以使用LEAD()进行过滤:

;with cte AS (    SELECT *,New_Column = (SUM(Qty) OVER(PARTITION BY Item, Location ORDER BY Week ROWS BETWEEN 1 FOLLOWING AND 5 FOLLOWING)*1.0)/4
                          ,Lead4Col = LEAD(week,5) OVER(PARTITION BY Item,Location ORDER BY Week)
                  FROM Table1
            )
SELECT *
FROM cte
WHERE Lead4Col IS NOT NULL

您还可以使用COUNT(Qty) OVER(PARTITION BY Item, Location ORDER BY Week ROWS BETWEEN 1 FOLLOWING AND 5 FOLLOWING)代替LEAD()进行过滤,以便在随后的4周内进行过滤。

编辑:我认为你实际上想要从计算中排除本周,所以稍微调整一下。

答案 3 :(得分:1)

尝试此查询:

SELECT 
T1.ITEM, 
T1.LOCATION, 
T1.WEEK, 
MAX(T1.QUANTITY) AS QUANTITY, 
AVG(T2.QUANTITY) AS NEW_COLUMN 
FROM TBL t1 LEFT JOIN TBL t2 
ON 
T1.ITEM=T2.ITEM AND T1.LOCATION=T2.LOCATION 
AND T2.WEEKNUMBER >T1.WEEK AND T2.WEEKNUMBER<T1.WEEK+5
GROUP BY t1.ITEM, t1.LOCATION, T1.WEEK

答案 4 :(得分:1)

与之前几乎相同,但最好使用SUM()/ 4来使用AVG

此外,我使用* 1.0从qty中生成十进制值,如果它是整数 - 您将在AVG操作后丢失小数部分。

SELECT *, 
       new_column = ( Avg(qty * 1.0) 
                      over( 
                        PARTITION BY item, location 
                        ORDER BY week ROWS BETWEEN 1 following AND 5 following 
                      )
                    ) 
FROM  table1 

答案 5 :(得分:0)

with x as 
(select *, lead(qty) over(partition by item order by week) as next_1 from tablename)
, y as 
(select *, lead(qty) over(partition by item order by week) as next_2 from x)
, z as 
(select *, lead(qty) over(partition by item order by week) as next_3 from y)
, w as 
(select *, lead(qty) over(partition by item order by week) as next_4 from z)
select item, location, qty, week, (next_1+next_2+next_3+next_4)/4 as new_column from w

这使用递归cte's。 lead函数选择下一行的数量值。当您从第一个cte转到第四个时,每次都会添加一个新列,因此您将在结尾处获得所有接下来的4周值。然后你就取平均值。