日期:2014-05-18  浏览次数:20486 次

一个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