我在 ORACLE 中的同一个查询中需要 2 个计数列
I need 2 count columns in the same query in ORACLE
我正在尝试使用 2 个 count() 函数获取公司已收到和发出的发票的唯一数量。在 invoices table 中有两列引用了同一个公司 ID(一个是发送发票的公司的 ID,另一个是接收发票的公司的 ID)
这是我尝试使用的代码:
SELECT K.ID,K.NAME,K.CITY, COUNT(*) AS NUM_OF_INVOICES_SENT, COUNT(*) AS NUM_OF_INVOICES_RECEIVED
FROM COMPANY K LEFT JOIN INVOICE F ON F.COMP_SNEDING = K.ID
GROUP BY K.NAME,K.ID,K.CITY
这是一个学校项目,所以我一点也不精通sql/oracle
实际数据发票:
实际数据公司:
给定实际数据的预期结果:
这是一种选择;它不使用 count
,而是使用 sum
和 case
表达式。
示例数据:
SQL> with
2 invoice (id, amount, comp_sending, comp_receiving) as
3 (select 1, 2000 , 1, 2 from dual union all
4 select 2, 28250, 3, 2 from dual union all
5 select 3, 8700 , 4, 1 from dual union all
6 select 4, 20200, 5, 3 from dual union all
7 select 5, 21500, 3, 4 from dual
8 ),
9 company (id, name, city, state) as
10 (select 1, 'Microsoft', 'Redmond' , 'Washington' from dual union all
11 select 2, 'Ubisoft' , 'Paris' , 'France' from dual union all
12 select 4, 'Starbucks', 'Seattle' , 'Washington' from dual union all
13 select 5, 'Apple' , 'Cupertino', 'California' from dual union all
14 select 3, 'Nvidia' , 'Cupertino', 'California' from dual
15 )
查询从这里开始:
16 select c.id, c.name,
17 sum(case when c.id = i.comp_sending then 1 else 0 end) cnt_sent,
18 sum(case when c.id = i.comp_receiving then 1 else 0 end) cnt_received
19 from company c left join invoice i on c.id in (i.comp_sending, i.comp_receiving)
20 group by c.id, c.name
21 order by c.id;
ID NAME CNT_SENT CNT_RECEIVED
---------- --------- ---------- ------------
1 Microsoft 1 1
2 Ubisoft 0 2
3 Nvidia 2 1
4 Starbucks 1 1
5 Apple 1 0
SQL>
如果将 CASE 表达式中的 0 替换为 NULL,则可以使用 COUNT。所以@Littlefoot 的查询变成了
select c.id, c.name,
COUNT(case when c.id = i.comp_sending then 1 else NULL end) cnt_sent,
COUNT(case when c.id = i.comp_receiving then 1 else NULL end) cnt_received
from company c left join invoice i on c.id in (i.comp_sending, i.comp_receiving)
group by c.id, c.name
order by c.id;
这是有效的,因为 COUNT
只计算那些在被计算的表达式中具有 non-NULL 值的行。
我正在尝试使用 2 个 count() 函数获取公司已收到和发出的发票的唯一数量。在 invoices table 中有两列引用了同一个公司 ID(一个是发送发票的公司的 ID,另一个是接收发票的公司的 ID) 这是我尝试使用的代码:
SELECT K.ID,K.NAME,K.CITY, COUNT(*) AS NUM_OF_INVOICES_SENT, COUNT(*) AS NUM_OF_INVOICES_RECEIVED
FROM COMPANY K LEFT JOIN INVOICE F ON F.COMP_SNEDING = K.ID
GROUP BY K.NAME,K.ID,K.CITY
这是一个学校项目,所以我一点也不精通sql/oracle
这是一种选择;它不使用 count
,而是使用 sum
和 case
表达式。
示例数据:
SQL> with
2 invoice (id, amount, comp_sending, comp_receiving) as
3 (select 1, 2000 , 1, 2 from dual union all
4 select 2, 28250, 3, 2 from dual union all
5 select 3, 8700 , 4, 1 from dual union all
6 select 4, 20200, 5, 3 from dual union all
7 select 5, 21500, 3, 4 from dual
8 ),
9 company (id, name, city, state) as
10 (select 1, 'Microsoft', 'Redmond' , 'Washington' from dual union all
11 select 2, 'Ubisoft' , 'Paris' , 'France' from dual union all
12 select 4, 'Starbucks', 'Seattle' , 'Washington' from dual union all
13 select 5, 'Apple' , 'Cupertino', 'California' from dual union all
14 select 3, 'Nvidia' , 'Cupertino', 'California' from dual
15 )
查询从这里开始:
16 select c.id, c.name,
17 sum(case when c.id = i.comp_sending then 1 else 0 end) cnt_sent,
18 sum(case when c.id = i.comp_receiving then 1 else 0 end) cnt_received
19 from company c left join invoice i on c.id in (i.comp_sending, i.comp_receiving)
20 group by c.id, c.name
21 order by c.id;
ID NAME CNT_SENT CNT_RECEIVED
---------- --------- ---------- ------------
1 Microsoft 1 1
2 Ubisoft 0 2
3 Nvidia 2 1
4 Starbucks 1 1
5 Apple 1 0
SQL>
如果将 CASE 表达式中的 0 替换为 NULL,则可以使用 COUNT。所以@Littlefoot 的查询变成了
select c.id, c.name,
COUNT(case when c.id = i.comp_sending then 1 else NULL end) cnt_sent,
COUNT(case when c.id = i.comp_receiving then 1 else NULL end) cnt_received
from company c left join invoice i on c.id in (i.comp_sending, i.comp_receiving)
group by c.id, c.name
order by c.id;
这是有效的,因为 COUNT
只计算那些在被计算的表达式中具有 non-NULL 值的行。