2015-01-05 4 views
0

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я знаю, что это задавали много раз, но все, что я хочу, является альтернативой.SQL-запрос - кредит, дебетование, баланс

В таблице, как показано ниже:

create table 
Account 
(Name varchar(20), 
TType varchar(5), 
Amount int); 

insert into Account Values 
('abc' ,'c', 500), 
('abc', 'c', 700), 
('abc', 'd', 100), 
('abc', 'd', 200), 

('ab' ,'c', 300), 
('ab', 'c', 700), 
('ab', 'd', 200), 
('ab', 'd', 200); 

Ожидаемый результат прост:

Name  Balance 
------ ----------- 
ab   600 
abc  900 

Запрос, который работал в:

select Name, sum(case TType when 'c' then Amount 
        when 'd' then Amount * -1 end) as balance 
from Account a1 
group by Name. 

Все, что я хочу, есть ли какой-либо запрос не поддерживает оператор case (например, подзапрос или самосоединение) для одного и того же результата?

+0

Как насчет DECODE? –

+0

Если ответ удовлетворяет вашему требованию, пожалуйста, ответьте на него как можно скорее. –

ответ

2

Конечно. Вы можете использовать второй запрос с пунктом where и union all:

select name 
,  sum(Amount) balance 
from Account a1 
where TType when 'c' 
group 
by  Name 
union 
all 
select name 
,  sum(Amount * -1) balance 
from Account a1 
where TType when 'd' 
group 
by  Name 

Или это, используя join с видом на инлайн:

select name 
,  sum(Amount * o.mult) balance 
from Account a1 
join (select 'c' cd 
     ,  1 mult 
     from dual 
     union all 
     select 'd' 
     ,  -1 
     from dual 
     ) o 
on  o.cd = a1.TType 
group 
by  Name 

Честно говоря, я бы предложил использовать case. ..

+1

Я имел в виду то же самое, но я думаю с точки зрения производительности, CASE лучше. Полностью согласен с @Patrick Hofman –

+0

@DARK_A: Мои 2 цента тоже :) –

+0

@PatrickHofman - спасибо! Меня задали этот вопрос на телефонном интервью, и он был довольно тупик, так что это было больше. – ssk

0

Используйте код ASCII символа и попробуйте оттуда. Это 100 для 'd' и 99 для 'c'. Непроверенный пример:

select Name, sum((ASCII(TType) - 100) * Amount * (-1)) + sum((ASCII(TType) - 99) * Amount * (-1)))) as balance from Account a1 group by Name. 

Я бы не рекомендовал использовать этот метод, но это способ достижения того, что вы хотите.

0
select t.Name, sum(t.cr) - sum(t.dr) as balance from (select Name, case TType when 'c' then sum(Amount) else 0 end as cr, case TType when 'd' then sum(Amount) else 0 end as dr from Account group by Name, TType) t group by t.Name; 

Это, безусловно, поможет вам!

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