连接两个表并使用sum函数的最佳方法是什么

时间:2019-01-17 19:42:20

标签: sql oracle

我想知道,以可接受/标准的方式实现以下输出的最佳方法是什么。

我试图加入两个表结果table1 org(同一表中的主键和外键)和表2许可证,在其中使用sum函数。

查询的输入将是parent_org_id,查询到的产品将使我回到上级/下级组织以及每个组的许可证计数。

在将结果与函数和条件组合在一起时,我遇到了问题。 我尝试了下面提供的查询。我知道这不符合标准。

  • 我已经使用or条件来绕过父级和子级记录。
  • 我还猜想我的查询对两个表都执行了扫描,因此可以避免考虑,因为两个表都是重表。

数据创建:

CREATE TABLE LICENSE (LICENSE_ID NUMBER NOT NULL PRIMARY KEY,   ORG_ID NUMBER,  QUANTITY NUMBER,    PRODUCT VARCHAR(10), START_DATE TIMESTAMP(6),   END_DATE TIMESTAMP(6));
Insert into LICENSE (LICENSE_ID,ORG_ID,QUANTITY,PRODUCT,START_DATE,END_DATE) values (1,222,10,'MOVIES', to_timestamp('01-JAN-18 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'),to_timestamp('04-JAN-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'));
Insert into LICENSE (LICENSE_ID,ORG_ID,QUANTITY,PRODUCT,START_DATE,END_DATE) values (2,222,3,'BOOKS',to_timestamp('01-JUN-18 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'),to_timestamp('18-DEC-18 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'));
Insert into LICENSE (LICENSE_ID,ORG_ID,QUANTITY,PRODUCT,START_DATE,END_DATE) values (3,222,6,'GOOGLE',to_timestamp('01-JAN-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'),to_timestamp('31-DEC-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'));
Insert into LICENSE (LICENSE_ID,ORG_ID,QUANTITY,PRODUCT,START_DATE,END_DATE) values (4,222,5, null, to_timestamp('01-JAN-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'),to_timestamp('31-DEC-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'));
Insert into LICENSE (LICENSE_ID,ORG_ID,QUANTITY,PRODUCT,START_DATE,END_DATE) values (5,222,8, null, to_timestamp('01-JAN-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'),to_timestamp('31-JAN-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'));
Insert into LICENSE (LICENSE_ID,ORG_ID,QUANTITY,PRODUCT,START_DATE,END_DATE) values (6,222,7,'BOOKS',to_timestamp('01-JAN-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'),to_timestamp('15-FEB-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'));
Insert into LICENSE (LICENSE_ID,ORG_ID,QUANTITY,PRODUCT,START_DATE,END_DATE) values (7,222,7,'MOVIES',to_timestamp('01-JAN-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'),to_timestamp('15-FEB-19 00:00:00.000000000','DD-MON-RR HH24:MI:SSXFF'));

CREATE TABLE ORG (ORG_ID NUMBER NOT NULL PRIMARY KEY, ORG_NAME VARCHAR2(10), PARENT_ORG_ID NUMBER, FOREIGN KEY (PARENT_ORG_ID) REFERENCES ORG(ORG_ID));
Insert into ORG (ORG_ID,ORG_NAME,PARENT_ORG_ID) values (111,'district-1',null);
Insert into ORG (ORG_ID,ORG_NAME,PARENT_ORG_ID) values (999,'district-2',null);
Insert into ORG (ORG_ID,ORG_NAME,PARENT_ORG_ID) values (222,'school-1',111);
Insert into ORG (ORG_ID,ORG_NAME,PARENT_ORG_ID) values (333,'school-2',111);
Insert into ORG (ORG_ID,ORG_NAME,PARENT_ORG_ID) values (444,'school-3',999);

查询:

select 
o1.org_id as orgId,
o1.org_name as orgName,
sum(nvl(quantity,0)) as totalLicense,
sum(case when END_DATE > systimestamp then quantity  else 0 end) as totalActiveLicense,
sum(case when END_DATE < systimestamp then quantity  else 0 end) as totalExpiredLicense,
sum(case when END_DATE > systimestamp-15 and END_DATE < systimestamp then quantity  else 0 end) as expiredInLast15Days,
sum(case when END_DATE > systimestamp-30 and END_DATE < systimestamp then quantity  else 0 end) as expiredInLast30Days,
sum(case when END_DATE > systimestamp-60 and END_DATE < systimestamp then quantity  else 0 end) as expiredInLast60Days,
sum(case when END_DATE < systimestamp+15 and END_DATE > systimestamp then quantity  else 0 end) as expiringInNext15Days,
sum(case when END_DATE < systimestamp+30 and END_DATE > systimestamp then quantity  else 0 end) as expiringInNext30Days,
sum(case when END_DATE < systimestamp+60 and END_DATE > systimestamp then quantity  else 0 end) as expiringInNext60Days
from org o1 left outer join (
select l.* from org o left outer join license l on o.org_id = l.org_id
where o.parent_org_id=111 or o.org_id=111
AND l.PRODUCT ='GOOGLE') license_info on o1.ORG_ID = license_info.org_id
where o1.parent_org_id=111 or o1.org_id=111
group by o1.org_id, o1.org_name;

查询应使我回到上级/下级组织和每个组织的许可证计数。

试图避免多项选择。

表结构和下面的预期输出。

许可证表1

License Table data

组织表2

Org Table data

输出

Output

对此将提供任何帮助!谢谢!

1 个答案:

答案 0 :(得分:0)

您可以从父母开始。
然后将许可证链接到父母和父母的孩子。

SELECT 
org1.org_id AS orgId,
org1.org_name AS orgName,
lic.product,
COALESCE(SUM(lic.quantity), 0) AS totalLicense,
SUM(CASE WHEN lic.END_DATE > systimestamp THEN lic.quantity ELSE 0 END) AS totalActiveLicense,
SUM(CASE WHEN lic.END_DATE < systimestamp THEN lic.quantity ELSE 0 END) AS totalExpiredLicense,
SUM(CASE WHEN lic.END_DATE > systimestamp-15 AND lic.END_DATE < systimestamp THEN lic.quantity ELSE 0 END) AS expiredInLast15Days,
SUM(CASE WHEN lic.END_DATE > systimestamp-30 AND lic.END_DATE < systimestamp THEN lic.quantity ELSE 0 END) AS expiredInLast30Days,
SUM(CASE WHEN lic.END_DATE > systimestamp-60 AND lic.END_DATE < systimestamp THEN lic.quantity ELSE 0 END) AS expiredInLast60Days,
SUM(CASE WHEN lic.END_DATE > systimestamp AND lic.END_DATE < systimestamp+15 THEN lic.quantity ELSE 0 END) AS expiringInNext15Days,
SUM(CASE WHEN lic.END_DATE > systimestamp AND lic.END_DATE < systimestamp+30 THEN lic.quantity ELSE 0 END) AS expiringInNext30Days,
SUM(CASE WHEN lic.END_DATE > systimestamp AND lic.END_DATE < systimestamp+60 THEN lic.quantity ELSE 0 END) AS expiringInNext60Days
FROM org org1 
JOIN org org2 ON (org2.org_id = org1.org_id OR org2.parent_org_id = org1.org_id)
LEFT JOIN license lic 
  ON lic.org_id = org2.org_id 
 AND lic.product IN ('GOOGLE')
WHERE org1.org_name = 'district-1'
GROUP BY org1.org_id, org1.org_name, lic.product
相关问题