Sql 移动平均/滚动平均
我在MS SQL中有两列,一列是序列号,另一列是值。我需要第三列,它给出该行和下一行2的值之和 前 所以我需要第三列,它的和是2+3+1,3+1+2等等,所以第八行和第九行没有任何值:Sql 移动平均/滚动平均,sql,sql-server,sql-server-2008,statistics,subquery,Sql,Sql Server,Sql Server 2008,Statistics,Subquery,我在MS SQL中有两列,一列是序列号,另一列是值。我需要第三列,它给出该行和下一行2的值之和 前 所以我需要第三列,它的和是2+3+1,3+1+2等等,所以第八行和第九行没有任何值: 1 2 6 2 3 6 3 1 4 4 2 5 5 1 6 7 2 7 8 3 9 2 这个解决方案是否可以是通用的,这样我就可以改变当前的窗口大小,将3个数字添加到一个更大的数字上,比如60
1 2 6
2 3 6
3 1 4
4 2 5
5 1 6
7 2 7
8 3
9 2
这个解决方案是否可以是通用的,这样我就可以改变当前的窗口大小,将3个数字添加到一个更大的数字上,比如60
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
如果
sno
字段不是顺序字段,您可以使用带聚合的row\u 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:创建一个表,列出所需的偏移量。0=当前行,1=下一行,-1=上一行,依此类推
SELECT * FROM (VALUES
(0),(1),(2)
) o(offset)
步骤2:在此模板中使用该偏移表(通过CTE或实际表格):
此外,如果SNo不是顺序的,则可以获取行\ u 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
下面是演示以下查询的示例:
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更改为60,并且创建如此多的连接将非常缓慢,而且会消耗资源。此查询无法与提供的示例数据一起工作。样本数据中缺少
SNo
6。因此,对于SNo,它是5,7,8加在一起的。抓到了,留恋。我只是想。。。不过,第二个查询应该可以正常工作。只需要将3修改为所需的数字。嗨,戈登,这是我从你的查询中得到的结果。(贴在上面)。我在上面加了订单。它应该将最后2行保留为空。你能帮忙吗?我们还必须将3和seqnum-2更改为所需的N和seqnum-(N-1),对吗?
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
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
m.RowNumber + 59