Вернуть 0, если не найдена запись для некоторых дат в запросе UNION - PullRequest
0 голосов
/ 15 февраля 2019

У меня следующий запрос

SELECT 
    COUNT(c.ID) as RECORD_COUNT, c.WEEK_START, c.LABEL
FROM
    (SELECT 
         a.ID, TRUNC(a.START_DATE,'IW') WEEK_START, 'YES' as LABEL 
     FROM 
         TABLE1 a
     UNION ALL
     SELECT 
         b.ID, TRUNC(b.START_DATE,'IW') WEEK_START, 'NO' as LABEL 
     FROM 
         TABLE1 b
     WHERE 
         FUNCTION(b.ID) = 'Test') AS c

То, что я получаю, - это количество записей в неделю, тех, которые появились в первом подзапросе с меткой YES, и количество записей внеделю, появившуюся во втором подзапросе с меткой NO.

Пример:

RECORD_COUNT   WEEK_START   LABEL
    100          1/28/2019  YES
     24          1/28/2019  NO
     81          2/4/2019   YES
    229          2/11/2019  YES
      6          2/11/2019  NO

Часто второй подзапрос не возвращает никаких записей, поэтому я пропускаю строки для некоторых дат.

В приведенном выше примере это былоничего не вернуть для строки NO для 2/4/2019.

Как я могу изменить свой запрос, чтобы он возвращал нули для строк, в которых нет данных?

Что бы яхотелось бы увидеть что-то вроде этого:

RECORD_COUNT   WEEK_START   LABEL
    100          1/28/2019  YES
     24          1/28/2019  NO
     81          2/4/2019   YES
      0          2/4/2019   NO
    229          2/11/2019  YES
      6          2/11/2019  NO

Ответы [ 2 ]

0 голосов
/ 15 февраля 2019

Я рекомендую помещать значения в столбцы, а не в строки:

select trunc(t.START_DATE, 'IW') as WEEK_START,
       count(*) as num_yes,
       sum(case when FUNCTION(b.ID) = 'Test' then 1 else 0 end) as num_nos
from table1
group by trunc(t.START_DATE, 'IW')
order by week_start;

Если вы хотите разделить строки, я бы отключил это:

with t as (
      select trunc(t.START_DATE, 'IW') as WEEK_START,
             count(*) as num_yes,
             sum(case when FUNCTION(b.ID) = 'Test' then 1 else 0 end) as num_nos
      from table1
      group by trunc(t.START_DATE, 'IW')
     )
select (case when l.label = 'YES' then t.num_yes else t.num_nos end) as record_count,
       t.week_start, l.label
from t cross join
     (select 'YES' as label from dual union all select 'NO' as label) l
order by week_start;
0 голосов
/ 15 февраля 2019

Есть более сложные способы сделать это, которые будут работать более широко.Но для вашего случая простой способ таков:

SELECT COUNT(c.ID) as RECORD_COUNT, c.WEEK_START, c.LABEL
FROM
(
    SELECT a.ID, 
           TRUNC(a.START_DATE,'IW') WEEK_START, 
           'YES' as LABEL 
    FROM TABLE1 a
    UNION ALL
    SELECT DECODE(FUNCTION(b.ID),'Test',b.ID,NULL) ID,
           TRUNC(b.START_DATE,'IW') WEEK_START, 
           'NO' as LABEL 
    FROM TABLE1 b
) as c
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...