Reputation: 25
I would like to get the following result but struggle to query the logic. What I want is to get the exact number of transactions/invoices after removing the canceled transactions (- negative custnb) from the table. SO with my sample table, I have 5 transactions, 2 are canceled, so I would like to only get the 3.
WANTED RESULT
Invoices Customers
3 3
TABLE
invoicenumber custnb invoiceid
1001 1 1001
1002 2 1002
1003 1 1003
1004 5 1004
1005 2 1005
2000001 -1 1001
2000002 -2 1002
Upvotes: 0
Views: 40
Reputation: 142705
The way you put it, this returns desired result; lines #1 - 9 represent sample data, so code you need begins at line #10.
SQL> with test (invoicenumber, custnb, invoiceid) as
2 (select 1001, 1, 1001 from dual union all
3 select 1002, 2, 1002 from dual union all
4 select 1003, 1, 1003 from dual union all
5 select 1004, 5, 1004 from dual union all
6 select 1005, 2, 1005 from dual union all
7 select 2001, -1, 1001 from dual union all
8 select 2002, -2, 1002 from dual
9 )
10 select count(invoicenumber) invoices,
11 count(custnb) customers
12 from test
13 where custnb > 0
14 and invoicenumber not in (select invoiceid
15 from test
16 where custnb < 0
17 )
18 ;
INVOICES CUSTOMERS
---------- ----------
3 3
SQL>
Upvotes: 1
Reputation: 1269543
One method is to aggregate at the invoice level and then count. Uncancelled invoices will have a "positive" custnb
:
select count(*) as num_invoices, count(distinct custnb) as num_customers
from (select invoiceid
from t
group by invoiceid
having min(custnb) > 0
) t;
If the custnb
and invoiceid
s line up exactly (as they now do), I would approach this using not exists
:
select count(*) as num_invoices, count(distinct custnb) as num_custoers
from t
where not exists (select 1
from t t2
where t2.invoiceid = t.invoiceid and
t2.custnb = - t.custnb
);
Or possibly using except
:
select count(*) as num_invoices, count(distinct custnb)
from ((select invoiceid, custnb
from t
where custnb > 0
) except
(select invoiceid, - custnb
from t
where custnb < 0
)
) ic
Upvotes: 0
Reputation: 1683
Untested but it would be something like this. Also, assumption is a customer may have multiple invoices.
select count(t.invoicenumber) invoices, count(distinct t.custnb) customers
from table t
where t.custnb > 0
and not exists (
select 1 from table t2
where t2.invoiceid = t.invoiceid
and t2.custnb < 0)
Upvotes: 0