Объединить 3 x sql-запросов в oracle db в 1

#sql #sorting #oracle-apex

#sql #сортировка #oracle-apex

Вопрос:

Во-первых, извиняюсь, если это кажется очень тривиальным, но я некоторое время пытался сделать это самостоятельно, но без особого успеха, поэтому прошу помощи. Ниже приведены 3 sql-запроса x (пункт 1,2,3), которые я хочу объединить в один запрос, дающий результат, показанный в пункте 4.(RDATE, CODATE, COMDATE — это столбцы в таблице «ORTABLE» и имеют тип «ДАТА» в формате мм / дд / гггг.СТАТУС также является одним из столбцов таблицы и имеет разные значения статуса, на которые устанавливаются фильтры для получения последующих подсчетов и упорядочения по месяцам.

 select to_char(RDATE, 'MON RRRR') AS MONTH,
       COUNT(STATUS) as "NEW" 
from ORTABLE 
GROUP BY to_char(RDATE, 'MON RRRR'), to_char(RDATE, 'RRRR MM') 
order by to_char(RDATE, 'RRRR MM');

Output
MONTH              NEW
MAR 2020          19
APR 2020            76
MAY 2020           33
JUN 2020            18
JUL 2020             27
AUG 2020           82
SEP 2020             29
OCT 2020            25
NOV 2020           53
DEC 2020            1
JAN 2021            40
FEB 2021            4

select to_char(CODATE, 'MON RRRR') AS MONTH,
       COUNT(STATUS) as "STATUSANB" 
from ORTABLE where STATUS IN ('STATUSA','STATUSB') 
GROUP BY to_char(CODATE, 'MON RRRR'), to_char(CODATE, 'RRRR MM') 
order by to_char(CODATE, 'RRRR MM') ;

Output
MONTH      STATUSANB
SEP 2020    9
OCT 2020    12
NOV 2020    2
DEC 2020    1
JAN 2021    39
FEB 2021    1

select to_char(COMDATE , 'MON RRRR') AS MONTH,
       COUNT(STATUS) as "Completed" 
from ORTABLE 
where STATUS IN ('STATUSC','STATUSD','STATUSE') 
GROUP BY to_char(COMDATE , 'MON RRRR'),to_char(COMDATE , 'RRRR MM') 
order by to_char(COMDATE , 'RRRR MM') ;

Output
MONTH   Completed
APR 2020    1
MAY 2020    71
JUN 2020    48
JUL 2020    34
AUG 2020    37
SEP 2020    19
OCT 2020    62
NOV 2020    3
DEC 2020    42
JAN 2021    23
FEB 2021    1
 

Я ищу, чтобы получить sql-запрос таким образом, чтобы я мог получать данные в формате ниже

 Month      NEW   STATUSANB      Completed
MAR 2020    19      
APR  2020   76                    1
MAY 2020    33                    71
JUN 2020    18                    48
JUL 2020    27                    34
AUG 2020    82                    37
SEP 2020    29         9           19
OCT 2020    25        12           62
NOV 2020    53         2           3
DEC 2020    1          1           42
JAN 2021    40        39           23
FEB 2021    4          1           1
 

Если кто-то может уделить немного времени и дать совет, это было бы оценено.Спасибо.
Прикрепление изображения для лучшего понимания вывода 3-кратных запросов и комбинированного вывода ожидаемые
выходные данные 3xsql-запросов и желаемый результат

Комментарии:

1. Примерные данные и желаемые результаты значительно прояснили бы вопрос.

Ответ №1:

Используйте условную агрегацию и объедините все 3 запроса в один:

 SELECT
    TO_CHAR(RDATE, 'MON RRRR') AS MONTH,
    COUNT(STATUS) AS "NEW",
    COUNT(CASE WHEN STATUS IN ('STATUSA', 'STATUSB') THEN 1 END) AS STATUSANB,
    COUNT(CASE WHEN STATUS IN ('STATUSC', 'STATUSD', 'STATUSE') THEN 1 END) AS Completed
FROM ORTABLE
GROUP BY
    TO_CHAR(RDATE, 'MON RRRR')
ORDER BY
    TO_CHAR(RDATE, 'MON RRRR');
 

Комментарии:

1. Вы видели какую-либо причину для ГРУППИРОВКИ ПО TO_CHAR (RDATE, ‘MON RRRR’ и TO_CHAR(RDATE, ‘RRRR MM’)?

2. @jarlh Нет, я этого не делаю. Я просто изучал это на самом деле.

3. @TimBiegeleisen Спасибо, это приближает меня. Единственная проблема заключается в том, что, поскольку RDATE используется как единственная дата для сортировки / группировки, количество обращений «STATUSANB» искажено, поскольку оно зависит от CODATE, а количество «Завершено» зависит от COMDATE.

4. Я даже не видел этого, и я думал, что здесь задействован только один столбец даты.

Ответ №2:

У вас разные столбцы даты. Один из способов справиться с этим — использовать union all , а затем агрегировать. В качестве предпочтения я trunc() предпочитаю вместо преобразования дат в строку, поэтому я буду использовать это:

 select trunc(dte, 'MON'),
       sum(is_new), sum(is_anb), sum(is_completed)
from ((select rdate as dte, 1 as is_new, null as is_anb, null as is_completed
       from ORTABLE
      ) union all
      (select codate as dte, null as is_new, 1, null
       from ORTABLE
       where STATUS IN ('STATUSA', 'STATUSB')
      ) union all
      (select comdate, null, null as is_new, 1 as is_completed
       from ORTABLE
       where STATUS IN ('STATUSC', 'STATUSD', 'STATUSE') 
      ) 
     ) d
group by trunc(dte, 'MON')
order by trunc(dte, 'MON');
 

Комментарии:

1. Спасибо. Это почти дает желаемый результат. Но одной из причин использования to_char было иметь столбец месяца в формате MON YYYY, а не mm / 01 / yyyy . Я пытаюсь преобразовать это обратно, используя to_char, но не уверен, будет ли он отсортирован так, как ожидалось МЕСЯЦ is_new is_anb is_completed 03/01/2020 19 — — 04/01/2020 76 — 1 05/01/2020 33 — 40 06/01/2020 18 — 47 07/01/2020 27 — 31 08/01/2020 82 — 36 09/01/2020 29 9 19 10/01/2020 25 12 62 11/01/2020 53 2 3 12/01/2020 11 42 01/01/2021 45 39 23 02/01/2021 4 1 1

2. @Ashwsur . , , Вы можете просто заменить trunc() на . to_char() Как я уже сказал, это мои предпочтения, чтобы избежать преобразования дат в строки.

Ответ №3:

Спасибо за все ответы и правки для моей публикации в формате таблицы новичков.. Приведенный ниже запрос работает для меня.Я пытался использовать формат MON / YYYY, но из-за строки в формате месяца порядок сортировки искажается.Если нет лучшего способа выполнить формат сортировки MON, я буду работать с форматом MM / YY..

 select to_char(dte, 'MM/YY') ,
   sum(is_new) , sum(is_anb) , sum(is_completed) 
 

из ((выберите rdate как dte, 1 как is_new, null как is_anb, null как is_completed
из ORTABLE
) объединить все
(выберите codate как dte, null как Enter, 1, null
из ORTABLE
, где STATUS IN (‘STATUSA’, ‘STATUSB’)
) объединить все
(выберите comdate, null, null как ввод, 1 как завершенный
из ТАБЛИЦЫ
, где STATUS IN (‘STATUSC’, ‘STATUSD’, ‘STATUSE’)
)
)
сгруппировать по to_char(dte, ‘ММ / ГГ’), to_char(dte, ‘ГГ / ММ’)
упорядочить по to_char(dte, ‘ГГ / ММ’);