Каков наилучший способ объединить две таблицы и использовать функцию суммы - PullRequest
0 голосов
/ 17 января 2019

Я хотел бы знать, каков наилучший способ достижения нижеуказанного результата приемлемым / стандартным способом.

Я пытаюсь объединить две таблицы результатов 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 голосов
/ 18 января 2019

Вы можете начать с родителя.
Затем свяжите лицензии с родителем и потомками родителя.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...