2014-11-25 98 views
2

我有以下表格是BankDetails和Transactiondetails。使用這兩個表格,我想獲取帳戶名稱的當前餘額。優化SQL查詢以計算帳戶餘額

表:

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 

對於不遵循表的正確命名約定,我深表歉意。任何幫助將不勝感激。

謝謝,

帕雷什Ĵ

+0

我通常建議,而不是一個'TranType'立柱稍稍讓'Amount'列包含正反兩方面的值,並使用一個約定(如正面是信用卡,負是借)。它使得大多數有用的查詢更容易。否則,就目前的設計而言,您可能會錯過'CHECK'約束來阻止* Amount發生負面影響 - 除非您希望申請負面信用的人員? – 2014-11-25 07:21:23

+0

@Damien_The_Unbeliever:TranType保持捕捉交易類型。在實際的表格中,它包含比CREDIT&Debit更多的細節。因此不能從表中刪除這些列。 – 2014-11-25 07:25:50

+0

@Damien_The_Unbeliever:可能有其他優化解決方案嗎?我的意思不是很複雜的查詢。 – 2014-11-25 07:27:28

回答

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
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 
+0

如果你能解釋你的代碼,那將會很棒。這將有助於OP以及其他SO用戶。 :) – jazzurro 2014-11-25 07:02:37

+0

有上述解決方案的錯誤夫婦。 1.不明確的列名稱'AccNo'。 2.由於您未在GROUP BY – 2014-11-25 07:03:04

+0

中包含其他列名稱,因此Group'by Bankdetails.AccName'中的'Bankdetails.AccName'仍然缺少'Bankdetails.OpBal' – bummi 2014-11-26 07:11:42