【发布时间】:2018-05-16 06:30:51
【问题描述】:
我有以下表格,分别是 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
我需要使用上述两个表格的帐户持有人姓名、帐户编号和当前余额。
以下是我的查询,我想获得优化的查询,即尽可能不使用子查询。 注意:在我的例子中,贷方 = 添加到账户的金额,借方 = 从账户中扣除的金额。
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
对于没有遵循正确的表格命名约定,我深表歉意。任何帮助将不胜感激。
谢谢,
帕雷什·J
【问题讨论】:
-
我通常会推荐,而不是让
TranType列只允许Amount列包含正值和负值并使用约定(例如,正数是贷方,负数是借方) .它使最有用的查询变得更加容易。否则,在您当前的设计中,您可能会缺少一个CHECKconstraint 来防止Amount成为负面的 - 除非您希望人们应用负面信用? -
@Damien_The_Unbeliever:TranType 一直用于捕获交易类型。在实际表中,它包含更多详细信息,而不仅仅是 CREDIT & Debit。因此不能从表中删除这些列。
-
@Damien_The_Unbeliever:还有其他可能的优化解决方案吗?我的意思是不太复杂的查询。
-
在这种情况下,我仍然会推荐适当的
CHECK约束 - 并且可能仍然 store 借记为负数,贷记为正数 - 就像我说的那样,它会产生大多数查询如果您可以简单地SUM金额列,在这些表格上会容易得多。
标签: sql sql-server sql-server-2008