2014-11-25 3 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 

Приносим извинения за несоблюдение надлежащих соглашений об именах для таблиц. Любая помощь будет оценена.

Благодаря,

Paresh J

+0

я обычно рекомендую, вместо того, 'TranType' столбец только позволяя' столбец Amount' содержит как положительные, так и отрицательные значения, и используя соглашения (например, позитивным является кредит, негатив дебет). Это делает самые полезные запросы намного проще. В противном случае, с вашим текущим дизайном, вам, вероятно, не хватает ограничения 'CHECK', чтобы * предотвратить *« Сумма »от отрицания - если вы не хотите, чтобы люди применяли отрицательные кредиты? –

+0

@Damien_The_Unbeliever: TranType сохранял тип транзакции. В фактической таблице он содержит больше деталей, чем просто CREDIT & Debit. Следовательно, не удаляйте эти столбцы из таблицы. –

+0

@Damien_The_Unbeliever: возможно ли любое другое оптимизированное решение? я имею в виду не очень сложный запрос. –

ответ

3

Идея заключается в том, чтобы сначала создать сумму для каждого типа транзакции, Debit и Credit. При этом присоедините его к 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

+0

Есть пары ошибок с вышеупомянутым решением. 1. Неоднозначное название столбца «AccNo». 2. Столбец «Bankdetails.AccName» недействителен в списке выбора, так как вы не включили другие имена столбцов в GROUP BY –

+0

, по-прежнему отсутствуют «Bankdetails.OpBal» в группе по – bummi

Смежные вопросы