借方,贷方未在同一日期显示正确的结果

时间:2014-02-26 11:52:03

标签: sql sql-server database sql-server-2008 sql-server-2008-r2

场景:我正在开发用户帐户,其中用户向帐户(信用卡)添加金额,他们从他们的帐户(借记卡)中提取他们的愿望金额,所有这些都是正确的但是当用户信用卡或借记卡在相同的日期时它给了我错误的结果(平衡)。这里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

Here is Result of my Query

3 个答案:

答案 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