一个SQL查询,计算行之间差值的问题,高手帮忙!~
视图 View_Test
结构为:
----------------------------
No | Date | Income | Payout | PersistDays | Balance |
-----------------------------
NULL | 2001-02-15 | NULL | 360 | <天数之差1> | <余额1> |
-----------------------------
12 | 2001-05-10 | 5000 | NULL | <天数之差2> | <余额2> |
------------------------------
NULL | 2002-01-01 | 2000 | NULL | <天数之差3> | <余额3> |
-------------------------------
3 | 2002-02-15 | NULL | 500 | <天数之差4> | <余额4> |
------------------------------
其中,1、“天数之差1”为第二行的Date与第一行的Date间相差天数(计算天数我会),“天数之差2”为第三行的Date与第二行的Date间相差天数,……,以此类推,直到最后一行的天数之差为当前时间和最后一行的Data之差
2、已知函数: dbo.GetStartMoney(),“余额1”为dbo.GetStartMoney()减去第一行的Payout,“余额2”等于“余额1”加上第二行的Income,“余额3”等于“余额2”加上第三行的Income,一次类推(这里的规则是,若这一行的Income为空Payout不为空,则减去Payout;否则加上Income, 它们不会同时为空。)
注意:字段No不是主键,它可以为NULL,并且行数不确定
谢谢了!~
------解决方案--------------------select * ,identity(int,1,1) as aa
into #aa
from View_Test
select a.no,a.date,a.income,a.payout,datediff(d,a.date,isnull(b.date,getdate())) as PersistDays ,
(case when a.aa=1 then dbo.GetStartMoney()-a.Payout else ( case when b.income is null then a.Balance- b.payout else a.Balance+ b.income end) end)
as Balance
from #aa a left outer join #aa b
on a.aa+1=b.aa
建议做成存储过程,想不出来更好的办法
------解决方案--------------------select
a.No,a.Date.a,Income,a.Payout,
datediff(day,a.date,isnull(b.date,getdate())) as PersistDays,
dbo.GetStartMoney()+(select sum(isnull(Income,0)-isnull(Payout,0)) from View_Test where date <=a.date) as Balance
from
View_Test a
left join
View_Test b
on b.Date=(select min(Date) from View_Test where Date> a.Date)
--没测试,也许效率很不怎么样
------解决方案--------------------写错了 临时表名,应该是:
1、SELECT IDENTITY(int,1,1) AS [id],* INTO #T1 FROM View_Test
2、A.[ID],A.[No],A.[Date],A.Income,A.Payout,DATEDIFF(day,A.[Date],B.[Date]) AS PersistDays,A.Balance
INTO #T2
FROM #T1 AS A LEFT OUTER JOIN #T1 AS B ON A.[id]+1=B.[id]
3、
DECLARE @Balance int --Update用
--先Update第一行,再Update别的行
UPDATE #T2 SET Balance=dbo.GetStartMoney()-Payout WHERE [id]=1
SET @Balance=0
UPDATE #T2 SET @Balance=@Balance+ISNULL(Income,0)-ISNULL(Payout,0),Balance=@Balance
WHERE [id]> 0
4、
SELECT * FROM #T2
5、
--删除临时表
DROP TABLE #T1,#T2