Ich möchte das folgende Ergebnis erhalten, habe aber Schwierigkeiten, die Logik abzufragen. Ich möchte die genaue Anzahl der Transaktionen / Rechnungen erhalten, nachdem die stornierten Transaktionen (- negative custnb) aus der Tabelle entfernt wurden. Also mit meiner Beispieltabelle habe ich 5 Transaktionen, 2 sind storniert, also möchte ich nur die 3 bekommen.

GESUCHTES ERGEBNIS

Invoices     Customers

3            3

TABELLE

invoicenumber         custnb     invoiceid

    1001              1          1001
    1002              2          1002
    1003              1          1003
    1004              5          1004
    1005              2          1005
    2000001           -1         1001
    2000002           -2         1002
0
Franco 23 Feb. 2020 im 15:05

3 Antworten

Beste Antwort

So wie Sie es ausdrücken, gibt dies das gewünschte Ergebnis zurück. Die Zeilen 1 bis 9 stellen Beispieldaten dar. Der benötigte Code beginnt also in Zeile 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>
1
Littlefoot 23 Feb. 2020 im 12:36

Eine Methode besteht darin, auf Rechnungsebene zu aggregieren und dann zu zählen. Nicht stornierte Rechnungen haben ein "positives" 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;

Wenn die custnb und invoiceid genau ausgerichtet sind (wie jetzt), würde ich dies mit not exists angehen:

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
                 );

Oder möglicherweise mit 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
0
Gordon Linoff 23 Feb. 2020 im 12:31

Ungetestet, aber es wäre so etwas. Es wird auch davon ausgegangen, dass ein Kunde möglicherweise mehrere Rechnungen hat.

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)
0
Gro 23 Feb. 2020 im 12:30