我试图通过在SQL中循环滚动平均来创建平滑函数。我目前的非循环方法代码如下:
CREATE TABLE #Input (
PartitionID int
, TimeID int
, Quantity float );
INSERT INTO #Input
VALUES
( 1, 1, 2 ),
( 1, 2, 4 ),
( 1, 3, 6 ),
( 1, 4, 16 ),
( 2, 4, 6 ),
( 2, 5, 1 ),
( 2, 6, 9 ),
( 2, 7, 2 );
SELECT *
FROM #Input;
-- Actual code
UPDATE i
SET i.Quantity = i2.c
FROM #Input i
JOIN ( SELECT PartitionID AS a
, TimeID AS b
, AVG(Quantity) OVER(Partition BY PartitionID ORDER BY TimeID ASC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS c
FROM #Input
) i2
ON i2.a = i.PartitionID
AND i2.b = i.TimeID;
-- /Actual code
SELECT *
FROM #Input;
我想创建这个循环,以便每个分区的第一行引用最后一行和反之。有什么想法吗?
编辑: 所需的输出是:
1 1 7.33
1 2 4
1 3 8.66
1 4 8
2 4 3
2 5 5.33
2 6 4
2 7 5.66
答案 0 :(得分:1)
这确实是一个非常有趣的问题。我所做的是尝试通过为每个PartitionID组添加两行来扩展原始表,一行具有max(TimeID)+1,另一行具有min(TimeID)-1,而[Quantity]值恰好相反。 例如,对于PartitionID = 1,我将添加两行,将原来的四行分为六行,如下所示(添加第一行和后两行)
( 1, 0, 16 )
( 1, 1, 2 ),
( 1, 2, 4 ),
( 1, 3, 6 ),
( 1, 4, 16 ),
( 1, 5, 2 )
整个查询如下:
--drop table #input;
CREATE TABLE #Input (
PartitionID int
, TimeID int
, Quantity float );
INSERT INTO #Input
VALUES[![enter image description here][1]][1]
( 1, 1, 2 ),
( 1, 2, 4 ),
( 1, 3, 6 ),
( 1, 4, 16 ),
( 2, 4, 6 ),
( 2, 5, 1 ),
( 2, 6, 9 ),
( 2, 7, 2 );
select * from #Input;
; with c as (
select partitionid, min_timeid = min(timeid), max_timeid = max(timeid)
from #Input
group by partitionid
)
, c2 as (
select c.PartitionID, TimeID= c.max_timeid+c.min_timeid-i.TimeID + case i.TimeID when c.max_timeid then -1 else 1 end , i.Quantity
from c
inner join #input i
on c.partitionid = i.PartitionID
and i.TimeID in (c.max_timeid, c.min_timeid)
union
select * from #Input
)
update i
set i.Quantity = i2.c
from #Input i
inner join ( SELECT PartitionID AS a
, TimeID AS b
, AVG(Quantity) OVER(Partition BY PartitionID ORDER BY TimeID ASC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS c
FROM c2
) i2
ON i2.a = i.PartitionID
AND i2.b = i.TimeID;
SELECT * from #input;
最终结果是