优化SQL查询以计算帐户余额

时间:2014-11-25 06:06:12

标签: sql sql-server sql-server-2008

我有以下表,它们是BankDetails和Transactiondetails。使用这两个表,我想获得帐户名称的当前余额。

表:

Create table Bankdetails
(
AccName varchar(50),
AccNo int,
OpBal numeric(18,2)
)

Create table Trandetails
(
AccNo int,
Amount numeric(18,2),
Trantype varchar(10)
)

为两个表插入脚本:

insert into Bankdetails values('A', 12345, 30000.00)
insert into Bankdetails values('B', 13345, 30000.00)
insert into Bankdetails values('C', 14545, 30000.00)
insert into Bankdetails values('D', 15045, 30000.00)

insert into Trandetails values(12345, 5000.00, 'Credit')
insert into Trandetails values(13345, 5000.00, 'Debit')
insert into Trandetails values(15045, 5000.00, 'Debit')
insert into Trandetails values(13345, 5000.00, 'Credit')
insert into Trandetails values(12345, 5000.00, 'Debit')
insert into Trandetails values(13345, 5000.00, 'Debit')
insert into Trandetails values(14545, 5000.00, 'Credit')
insert into Trandetails values(15045, 5000.00, 'Debit')
insert into Trandetails values(14545, 5000.00, 'Debit')

输出将是这样的:

AccName Accno    CurrBal
  A     12345   30000.00 
  B     13345   25000.00
  C     14545   30000.00
  D     15045   20000.00

我需要使用以上两个表格的帐户Holdername,帐号和当前余额。

下面是我的查询,我希望得到优化的查询,即如果可能的话,不使用子查询。 注意:就我而言,信用=帐户中的金额和借方=从帐户中扣除的金额。

Select bd.accname, bd.accno, 
(bd.opbal - isnull((select SUM(Amount) from Trandetails where Trantype = 'Debit' and accno = bd.accno group by accno),0) + isnull((select SUM(Amount) from Trandetails where Trantype = 'Credit'  and accno = bd.accno group by accno),0)) as Bal
From Bankdetails BD inner join Trandetails TD on td.AccNo = bd.AccNo
group by bd.accno, bd.accname, bd.opbal

对于没有遵循表的正确命名约定,我深表歉意。任何帮助将不胜感激。

谢谢,

Paresh J

3 个答案:

答案 0 :(得分:3)

我们的想法是首先为每种交易类型DebitCredit生成总和。然后,将其加入Bankdetails以计算当前余额。

;with cte as(
    select
        AccNo,
        Credit = sum(case when TranType = 'Credit' then Amount else 0 end),
        Debit = sum(case when TranType = 'Debit' then Amount else 0 end)
    from Trandetails
    group by
        AccNo
)
select
    bd.AccName,
    bd.AccNo,
    CurrBal = bd.opBal - c.Debit + c.Credit
from BankDetails bd
inner join cte c
    on c.Accno = bd.Accno

答案 1 :(得分:0)

对于那些关心表现的人,请点击这里;

Select   B.AccName
        ,B.AccNo
        ,(B.OpBal + SUM( Case When TranType = 'Credit' Then Amount Else Amount* -1 End)) CurrBal
From Bankdetails B
Left Join Trandetails T
On B.AccNo = T.AccNo
Group By B.AccName, B.AccNo, B.OpBal;

<强> SQL Fiddle

答案 2 :(得分:-1)

SELECT 
    Bankdetails.AccName
    , Bankdetails.AccNo
    , Bankdetails.OpBal 
        + SUM(CASE WHEN TranType = 'Credit' THEN  Amount ELSE 0 END)
        - SUM(CASE WHEN TranType = 'Debit' THEN  Amount ELSE 0 END)
    AS 'CurrBal'
FROM Trandetails
    INNER JOIN Bankdetails ON Bankdetails.AccNo = Trandetails.AccNo
GROUP BY Bankdetails.AccNo, Bankdetails.AccName