Reputation: 426
I have table structure like
From|To |Amt |In_out
A | B | 100 |0
B | A | 200 |1
C | D | 250 |0
where the last column defines the direction of cash flow I want to get the output as
From | To | Amount Transacted | Debited | Credited
A | B | 300 |100 | 200
C | D | 250 |250 | 0
I tried various queries like
select DISTINCT r.to,r.to,r.Amt,r.In_out
,sum(r.Amt) as credited
from
Records as r
join
Records as s
on
(r.from <> s.from and r.to == s.from)
where
r.from <>s.from
--GROUP by r.from
can Anyone help me with this?
Upvotes: 0
Views: 486
Reputation: 10206
Not sure of your RDBMS: Oracle or SQLite.
Anyway here's a way to achieve this in standard SQL
The trick is to inverse the From and To columns if the In_out is 1, in a UNION query, in order to GROUP the pairs of account correctly
SELECT u.From, u.To, SUM(Amt) AS "Amount Transacted",
SUM(CASE WHEN In_out=0 THEN Amt ELSE 0 END) AS Debited,
SUM(CASE WHEN In_out=1 THEN Amt ELSE 0 END) AS Credited
FROM
(
SELECT In_out, From, To, Amt FROM Records WHERE In_Out = 0
UNION ALL
SELECT In_out, To, From, Amt FROM Records WHERE In_Out = 1
) u
GROUP BY u.From, u.To
Upvotes: 1
Reputation: 50163
You want greatest() / least()
:
select least(from, to) from, greatest(from, to) to,
sum(amt) AmountTransacted,
sum(case when In_out = 0 then Amt else 0 end) Debited,
sum(case when In_out = 1 then Amt else 0 end) Credited
from table t
group by least(from, to), greatest(from, to);
Upvotes: 2
Reputation: 1269563
In many databases, you can use least()
and greatest()
:
select least(from, to), greatest(from, to),
sum(amount),
sum(case when in_out = 0 and from = least(from, to) or
in_out = 1 and to = least(from, to)
then amount else 0
end) as debited,
sum(case when in_out = 0 and to = least(from, to) or
in_out = 1 and from = least(from, to)
then amount else 0
end) as credited
from records
group by least(from, to), greatest(from, to);
If your database doesn't support these functions, you can use case
expressions to accomplish the same thing.
Upvotes: 2