create table ta(日期 datetime, 金额 int)insert into ta
select '20130101', 20 union all
select '20130203', 50 union all
select '20130225', 35 union all
select '20130301', 40 union all
select '20130502', 80
select t1.日期,
t1.金额,
(select SUM(金额) from ta t2 where t2.日期 <= t1.日期) as 累计
from ta t1
/*
日期 金额 累计
2013-01-01 00:00:00.000 20 20
2013-02-03 00:00:00.000 50 70
2013-02-25 00:00:00.000 35 105
2013-03-01 00:00:00.000 40 145
2013-05-02 00:00:00.000 80 225
*/
select '20130101', 20 union all
select '20130203', 50 union all
select '20130225', 35 union all
select '20130301', 40 union all
select '20130502', 80
select t1.日期,
t1.金额,
(select SUM(金额) from ta t2 where t2.日期 <= t1.日期) as 累计
from ta t1
/*
日期 金额 累计
2013-01-01 00:00:00.000 20 20
2013-02-03 00:00:00.000 50 70
2013-02-25 00:00:00.000 35 105
2013-03-01 00:00:00.000 40 145
2013-05-02 00:00:00.000 80 225
*/
select a.* ,lj=(select SUM(money ) from #tb b where b.date <=a.date ) from #tb a
INSERT INTO #a
select '20130101', 20 UNION ALL
select '20130203', 50 UNION ALL
select '20130225', 35 UNION ALL
select '20130301', 40 UNION ALL
select '20130502', 80SELECT a.日期,a.金额,
(SELECT SUM(isnull(金额,0)) FROM
(SELECT ROW_NUMBER()OVER(ORDER BY 日期)id,CONVERT(VARCHAR(50),日期,112) 日期,金额
FROM #a)b WHERE a.id>=b.id )as 累计
FROM (
SELECT ROW_NUMBER()OVER(ORDER BY 日期)id,CONVERT(VARCHAR(50),日期,112) 日期,金额
FROM #a)a
---------------------------------------------------------
日期 金额 累计
-------------------------------------------------- ----------- -----------
20130101 20 20
20130203 50 70
20130225 35 105
20130301 40 145
20130502 80 225(5 行受影响)
create table #ta(日期 datetime, 金额 int)
insert into #ta
select '20130101', 20 union all
select '20130203', 50 union all
select '20130225', 35 union all
select '20130301', 40 union all
select '20130502', 80select *
from #ta t1
CROSS APPLY (select SUM(金额) 累计 from #ta where 日期 <= t1.日期) t2
insert into #tb
select '20130101' ,20 union all
select '20130203' ,50 union all
select '20130225' ,35 union all
select '20130301' ,40 union all
select '20130502' ,80 select a.* ,lj=(select SUM(money ) from #tb b where b.date <=a.date ) from #tb aselect a.*,ab.lj from #tb a
cross apply (select lj= SUM(money ) from #tb b where b.date <=a.date ) abselect a.date ,lj=SUM(b.money ) from #tb a join #tb b on b.date <=a.date
group by a.date order by a.date drop table #tb
果然有高手!都是一个思路,就是根据每一条的ID,去sum这条之前的金额,不知道这样的效率和游标比起来如何?现在重要的效率
go
insert into ta
select '20130101', 20 union all
select '20130203', 50 union all
select '20130225', 35 union all
select '20130301', 40 union all
select '20130502', 80
go
ALTER TABLE ta ADD tot INT, isupd BIT NOT NULL DEFAULT 0
GO
CREATE INDEX idx1 ON ta(日期)
go
DECLARE @n int
SET @n=0
--SET ROWCOUNT 3
--SELECT @n
--WHILE @@ROWCOUNT>0
UPDATE a SET @n=金额 + @n,tot=@n,isupd=1 FROM ta a WITH(INDEX=idx1) WHERE isupd=0
--SET ROWCOUNT 0
GO
select * from ta
/*
2013-01-01 00:00:00.000 20 20 1
2013-02-03 00:00:00.000 50 70 1
2013-02-25 00:00:00.000 35 105 1
2013-03-01 00:00:00.000 40 145 1
2013-05-02 00:00:00.000 80 225 1
*/
go
drop table ta
go如果感觉一次的io峰值很高, 可以去掉那四行的注释, 把set rowcount 3改为5000或者10000, 即每个批次处理这么多行。
UPDATE TOP(3) a SET @n=金额 + @n,tot=@n,isupd=1 FROM ta a WITH(INDEX=idx1) WHERE isupd=0
这样的写法。
select FVOUID,FYEARNAME,FPERIODNAME,FVOUKEY,FEXP,FACCNUMBER,FDAMOUNT,FCAMOUNT,
(select sum(FDAMOUNT) from Voucher_ where FACCNUMBER = a.FACCNUMBER and FVOUID<=a.FVOUID) as SumD,
(select sum(FCAMOUNT) from Voucher_ where FACCNUMBER = a.FACCNUMBER and FVOUID<=a.FVOUID) as SumC
from Voucher_ a
Voucher_表有几个索引,FACCNUMBER 是非唯一索引,FVOUID没有加入索引,好像是这个原因
;with cte as
(
select rn=1, DATE= max(DATE),lj=SUM(money) from (select top 1 * from #tb) a
union all
select a.rn+1,b.date,a.lj +b.money from cte a join (select rn=ROW_NUMBER () over (order by date),date,money from #tb ) b on b.rn =a.rn +1
)select * from cte
insert into #tb
select '20130101' ,20 union all
select '20130203' ,50 union all
select '20130225' ,35 union all
select '20130301' ,40 union all
select '20130502' ,80 select date,sum(money) over(order by date) from #tb
date
------------ -----------
20130101 20
20130203 70
20130225 105
20130301 145
20130502 225(5 行受影响)(1285830 行受影响) 耗时43秒,环境:Xeon 5606 @2.13GHz win2008 sqlserver2012
DROP TABLE test
go
CREATE TABLE test
(
dt nvarchar(10) ,
num int
)
GOINSERT INTO test (dt , num)
SELECT '20130101' , 20 UNION ALL
SELECT '20130203' , 50 UNION ALL
SELECT '20130225' , 35 UNION ALL
SELECT '20130502' , 40 UNION ALL
SELECT '20130502' , 80
---------------------------------執行查詢----------------------
SELECT dt , num , SUM(num) OVER(ORDER BY dt) FROM test/*
dt num
---------- ----------- -----------
20130101 20 20
20130203 50 70
20130225 35 105
20130502 40 225
20130502 80 225(5 row(s) affected)
*/