我有一张桌子(TableA),有点像这样:
Id Type TimeBlock Value
1 1 1 100
2 1 1 150
3 2 1 100
4 1 1 1000
5 1 1 100
6 1 2 50
6 1 2 50
我希望能够通过TimeBlock对Value列进行SUM
分区,但是根据某些条件我只想SUM
行。如果当前总和值,则条件仅为SUM
行
大于或等于值列
我假设查询将从以下内容开始:
DECLARE @Amount int = 500;
SELECT *, @Amount - SUM (Value) OVER (PARTITION BY TimeBlock ORDER BY Id) AS Sum
FROM TableA
我希望结果如下:
Id Type TimeBlock Value Sum
1 1 1 100 400 (500 - 100)
2 1 1 150 250 (400 - 150)
3 2 1 1000 NULL (This does not count since its of type = 2 and 250 < 1000)
4 1 1 1000 0 (250 - 1000 = -750 there its filled the @Amount so we'll leave it at 0)
5 1 1 100 NULL (Since @Amount has been filled anything that comes after in this time block is NULL)
6 1 2 50 450 (500 - 50)
6 1 2 50 400 (450 - 50)
正如您所看到的,我需要能够获取SUM
函数的当前值,以便能够将其与Value列进行比较,而我不确定该如何操作。我希望能够做一些像
DECLARE @Amount int = 500;
SELECT *, @Amount - SUM (CASE WHEN Type = 2 AND SUM(Value) OVER (PARTITION BY TimeBlock ORDER BY Id) < Value THEN 0 ELSE Value END) OVER (PARTITION BY TimeBlock ORDER BY Id) AS Sum
FROM TableA
修改 Type = 1 - 无论如何,将Value列相加 Type = 2 - 如果当前总和值大于或等于Value
,则仅对行中的Value列求和答案 0 :(得分:0)
虽然它是基于有争议的运行总和古怪更新(由Jeff Moden here更详细地描述),但以下代码将起作用:
-- prepare temporary table with required clustered index to control processing order
create table #t (
Id int not null primary key nonclustered
,Type int not null
,TimeBlock int not null
,Value int not null
,RunningSum int null
,unique clustered (TimeBlock,Id)
);
-- load temporary table from data source,
-- hard-coded data used for this example.
insert #t(Id, Type,TimeBlock,Value)
values
(1, 1, 1, 100)
,(2, 1, 1, 150)
,(3, 2, 1, 100)
,(4, 1, 1, 1000)
,(5, 1, 1, 100)
,(6, 1, 2, 50)
,(7, 1, 2, 50);
go
declare @sum int = 0
,@TimeBlock int = -1;
update #t
set @sum = case when TimeBlock <> @TimeBlock then 500 - Value
when Value > @sum then @sum
else @sum - Value
end
,@TimeBlock = TimeBlock
,RunningSum = @sum
from #t with (TABLOCKX)
where Type = 1
option (MAXDOP 1)
;
-- display results
select * from #t
drop table #t;
go
输出:
Id Type TimeBlock Value RunningSum
----------- ----------- ----------- ----------- -----------
1 1 1 100 400
2 1 1 150 250
3 2 1 100 NULL
4 1 1 1000 250
5 1 1 100 150
6 1 2 50 450
7 1 2 50 400
特别注意,这要求聚簇索引与排序相同,并确保其他管理员不会修改此数据,将数据复制到具有所需聚簇索引的临时表中。此外,选项(MAXDOP 1)设置为确保优化程序不会尝试查询的并行化,并且进行EXCLUSIVE锁定以便(如果不需要临时表)不进行修改在处理过程中可能会出现表格。
更新: Quirky Update 是有争议的,因为虽然它已知自Sybase SQL Server早期起作用,但它依赖于SQL Server的未记录功能不保证在将来的版本中支持。