我在MS SQL中有2列,其中一列是序列号。和其他是价值观。我需要一个thrird列,它给出了该行和下一个2中值的总和。
实施例
SNo values
1 2
2 3
3 1
4 2
5 6
7 9
8 3
9 2
所以我需要第三列,其总和为2 + 3 + 1,3 + 1 + 2和So,所以第8和第9行将没有任何值:
1 2 6
2 3 6
3 1 4
4 2 5
5 1 6
7 2 7
8 3
9 2
解决方案是否可以通用,以便我可以将当前窗口大小变为将更多3个数字添加到更大的数字,例如60。
答案 0 :(得分:1)
如果sno
字段不是连续的,您可以将row_number()
与聚合一起使用:
with ss as (
select sno, values, row_number() over (order by sno) as seqnum
from s
)
select s1.sno, s1.values,
(case when count(s2.values) = 3 then sum(s2.values) end) as avg3
from ss s1 left outer join
ss s2
on s2.seqnum between s1.seqnum - 2 and s1.seqnum
group by s1.sno, s1.values;
答案 1 :(得分:1)
以下是展示以下查询的SQL Fiddle:
WITH TempS as
(
SELECT s.SNo, s.value,
ROW_NUMBER() OVER (ORDER BY s.SNo) AS RowNumber
FROM MyTable AS s
)
SELECT m.SNo, m.value,
(
SELECT SUM(s.value)
FROM TempS AS s
WHERE RowNumber >= m.RowNumber
AND RowNumber <= m.RowNumber + 2
) AS Sum3InRow
FROM TempS AS m
在你的问题中,你要求总计3个连续值。您修改了问题,说明您需要总和的连续记录数可能会发生变化。在上面的查询中,您只需将m.RowNumber + 2
更改为您需要的内容。
因此,如果您需要60,请使用
m.RowNumber + 59
正如您所看到的,它非常灵活,因为您只需要更改一个数字。
答案 2 :(得分:0)
select one.sno, one.values, one.values+two.values+three.values as thesum
from yourtable as one
left join yourtable as two
on one.sno=two.sno-1
left join yourtable as three
on one.sno=three.sno-2
或者,根据您的评论中的要求,您可以这样做:
select sno, sum(values)
over (
order by sno
rows between current row and 3 following
)
from yourtable
答案 3 :(得分:0)
如果您需要一个完全通用的解决方案,您可以在其中求和,例如,当前行+下一行+第5行:
步骤1:创建一个列出所需偏移的表格。 0 =当前行,1 =下一行,-1 =上一行等
SELECT * FROM (VALUES
(0),(1),(2)
) o(offset)
步骤2:在此模板中使用该偏移表(通过CTE或实际表格):
WITH o AS (SELECT * FROM (VALUES (0),(1),(2) ) o(offset))
SELECT
t1.sno,
t1.value,
SUM(t2.Value)
FROM @t t1
INNER JOIN @t t2 CROSS JOIN o
ON t2.sno = t1.sno + o.offset
GROUP BY t1.sno,t1.value
ORDER BY t1.sno
此外,如果SNo不是连续的,您可以获取ROW_NUMBER()并加入其中。
WITH
o AS (SELECT * FROM (VALUES (0),(1),(2) ) o(offset)),
t AS (SELECT *,ROW_NUMBER() OVER(ORDER BY sno) i FROM @t)
SELECT
t1.sno,
t1.value,
SUM(t2.Value)
FROM t t1
INNER JOIN t t2 CROSS JOIN o
ON t2.i = t1.i + o.offset
GROUP BY t1.sno,t1.value
ORDER BY t1.sno