如何一次从单个表进行多个查询并进行数学计算?

时间:2020-02-23 12:05:38

标签: sql oracle

我想得到以下结果,但是很难查询逻辑。 我想要的是从表中删除已取消的交易(-负custnb)后,获得交易/发票的确切数量。因此,在我的示例表中,我有5笔交易,其中2笔被取消,所以我只想得到3笔。

想要的结果

Invoices     Customers

3            3

invoicenumber         custnb     invoiceid

    1001              1          1001
    1002              2          1002
    1003              1          1003
    1004              5          1004
    1005              2          1005
    2000001           -1         1001
    2000002           -2         1002

3 个答案:

答案 0 :(得分:1)

您放置它的方式,将返回期望的结果;第1-9行代表示例数据,因此您需要的代码从第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 :(得分:0)

未经测试,但是会是这样。另外,假设客户可能有多张发票。

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)

答案 2 :(得分:0)

一种方法是在发票级别进行汇总,然后进行计数。取消的发票将具有“正” 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;

如果custnbinvoiceid完全对齐(就像现在一样),我将使用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
                 );

或可能使用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