场景:我正在开发用户帐户,其中用户向帐户(信用卡)添加金额,他们从他们的帐户(借记卡)中提取他们的愿望金额,所有这些都是正确的但是当用户信用卡或借记卡在相同的日期时它给了我错误的结果(平衡)。这里refno是用户的参考。这是我的查询
declare @startdate date='2013-01-02',
@enddate date='2013-01-12';
With summary(id,refno,transdate,cr,dr,balance)
as
(
select id,
RefNo,
Cast(TransDate as Varchar),
cr,
dr,
(cr-dr)+( Select ISNULL(Sum(l.Cr-l.Dr) ,0)
From Ledger l
Where l.TransDate<Ledger.TransDate and refno=001 ) as balance
from Ledger
),
openingbalance(id,refno,transdate,cr,dr,balance)
As (
select top 1 '' id,'OPENING BAL','','','',balance
from summary
where transdate<@startdate
order by transdate desc
)
select *
from openingbalance
union
Select *
From summary
where transdate between @startdate and @enddate and refno=001 order by transdate
答案 0 :(得分:1)
如果您使用的是SQL 2012或更高版本,则代替
SELECT id, RefNo, TransDate,cr, dr, (cr-dr) + (Select ISNULL(Sum(l.Cr-l.Dr) ,0)
FROM Ledger l
WHERE Cast(l.TransDate as datetime) < Cast(Ledger.TransDate as datetime)
AND refno=001) as balance from Ledger
使用:
SELECT id, RefNo, TransDate, cr, dr, SUM(cr- dr) OVER(ORDER BY TransDate ROWS
BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS balance
答案 1 :(得分:0)
问题是因为当您查询以前的余额时,您只查看比当前记录早transdate
的记录,这意味着不会包含任何具有相同日期的记录。 / p>
这里的解决方案是使用更独特的顺序值,在您的示例中,您可以使用ID值作为顺序标识符。但是,ID值并不总是确保序列的最佳值。我建议扩展您的transdate
列以使用更精确的值并包括交易时间。如果您可以保证在给定的秒内不会进行多次交易,则秒数可能足够精确,但无论您决定什么,您都需要确信不会有任何重复。
为了尝试提供可与现有数据一起使用的代码更改解决方案,您可以尝试以下操作,使用id
值来确定记录是否在当前记录之前:
更改以下行:
Where l.TransDate<Ledger.TransDate and refno=001 ) as balance
到此:
Where l.ID<Ledger.ID and refno=001 ) as balance
答案 2 :(得分:0)
在@musefan提示后,我对查询进行了更改,它正在按我的意愿工作。这是查询日期基础
declare @startdate date='2013-01-02',
@enddate date='2013-01-12';
With summary(id,refno,transdate,cr,dr,balance)
as
(
select id,
RefNo,
TransDate,
cr,
dr,
(cr-dr)+( Select ISNULL(Sum(l.Cr-l.Dr) ,0)
From Ledger l
Where Cast(l.TransDate as datetime)< Cast(Ledger.TransDate as datetime) and refno=001 ) as balance
from Ledger
),
openingbalance(id,refno,transdate,cr,dr,balance)
As (
select top 1 '' id,'OPENING BAL','','','',balance
from summary
where transdate<@startdate
order by transdate desc
)
select id,refno,Cast(TransDate as varchar) as datetime,cr,dr,balance
from openingbalance
union
Select id,refno,Cast(TransDate as varchar)as datetime,cr,dr,balance
From summary
where transdate between @startdate and @enddate and refno=001 order by Cast(TransDate as varchar)
和另一个基于查询ID的
declare @startdate date='2013-01-02',
@enddate date='2013-01-12';
With summary(id,refno,transdate,cr,dr,balance)
as
(
select id,
RefNo,
TransDate,
cr,
dr,
(cr-dr)+( Select ISNULL(Sum(l.Cr-l.Dr) ,0)
From Ledger l
Where l.id < Ledger.id and refno=001 ) as balance
from Ledger
),
openingbalance(id,refno,transdate,cr,dr,balance)
As (
select top 1 '' id,'OPENING BAL','','','',balance
from summary
where transdate<@startdate
order by transdate desc
)
select id,refno,Cast(TransDate as varchar) as datetime,cr,dr,balance
from openingbalance
union
Select id,refno,Cast(TransDate as varchar)as datetime,cr,dr,balance
From summary
where transdate between @startdate and @enddate and refno=001 order by id