Объединить значения трех запросов / трех полей? - PullRequest
1 голос
/ 14 июня 2019

Мне нужно создать отчет, который смотрит на:

  • Новые заказы, сделанные до 5 вечера
  • Новые заказы после 5 вечера
  • Заказы выполнены в тот же день

(тот же день классифицируется как заказ, сделанный до 17:00 и отправленный до 19:00)

Таблицы должны быть в формате:


Дата - Тип - Pre_5 - After_5 - Итого - Same_Day

В идеале вся информация должна отображаться в одной строке, их должно быть две строки для каждого дня, одна строка, где type = CO, и другая, где type = DO.

В настоящее время при выполнении запроса он возвращает данные с дополнительными строками, некоторые из которых содержат нули.

Подходы, которые я уже попробовал:

  • Просто группировка по значениям
  • Создание трех запросов и запуск объединения по результатам
  • Подзапросы для каждого CASE

Следующий код предназначен для запроса, который пытается просто сгруппировать.

SELECT
  COUNT(ORDER_ID),
  TO_CHAR(CREATION_DATE, 'DD/MM/YYYY'),
  CASE
    WHEN ORDER_TYPE = 31
    THEN 'CO'
    ELSE 'DO'
  END AS "TYPE" ,
  CASE
    WHEN TO_CHAR(CREATION_DATE, 'HH24') < 17
    THEN NVL(COUNT(ORDER_ID),0)
  END AS "Pre_5",
  CASE
    WHEN TO_CHAR(CREATION_DATE, 'HH24') >= 17
    THEN NVL(COUNT(ORDER_ID),0)
  END AS "After_5",
  CASE
    WHEN TO_CHAR(shipped_date, 'DD/MM/YYYY') = TO_CHAR(CREATION_DATE,
      'DD/MM/YYYY')
    AND TO_CHAR(CREATION_DATE, 'HH24') < 17
     AND TO_CHAR(shipped_date, 'HH24') <= 19
    THEN COUNT(ORDER_ID)
   END AS "SAME DAY"
FROM
  ORDER_HEADER
WHERE
   CLIENT_ID       = '*****'
 AND creation_date > sysdate -7
GROUP BY
  ORDER_TYPE,
  TO_CHAR(CREATION_DATE, 'DD/MM/YYYY'),
  TO_CHAR(CREATION_DATE, 'HH24'),
  TO_CHAR(SHIPPED_DATE, 'HH24'),
  TO_CHAR(SHIPPED_DATE, 'DD/MM/YYYY')

Код для Pre_5

SELECT
      COUNT(ORDER_ID) AS PRE_5,
      CASE
    WHEN ORDER_TYPE = 31
    THEN 'CO'
    ELSE 'DO'
  END AS "TYPE",
  TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')  
    FROM
      ORDER_HEADER
    WHERE
      TO_CHAR(CREATION_DATE, 'HH24') < 17
    AND CLIENT_ID                    ='*****'
    AND creation_date                > sysdate -7
    GROUP BY ORDER_TYPE, TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')
    ORDER BY TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')

Код для After_5

SELECT
      COUNT(ORDER_ID) AS AFTER_5,
      CASE
    WHEN ORDER_TYPE = 31
    THEN 'CO'
    ELSE 'DO'
  END AS "TYPE",
  TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')
    FROM
      ORDER_HEADER
    WHERE
      TO_CHAR(CREATION_DATE, 'HH24') >= 17
    AND CLIENT_ID                     ='*****'
    AND creation_date                 > sysdate -1
       GROUP BY ORDER_TYPE, TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')
    ORDER BY TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')

Код для Same_Day

SELECT
      COUNT(ORDER_ID) AS SAME_DAY,
      CASE
    WHEN ORDER_TYPE = 31
    THEN 'CO'
    ELSE 'DO'
  END AS "TYPE",
  TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')
    FROM
      ORDER_HEADER
    WHERE
      TO_CHAR(shipped_date, 'DD/MM/YYYY' ) = TO_CHAR(CREATION_DATE,
      'DD/MM/YYYY')
    AND TO_CHAR(CREATION_DATE, 'HH24') < 17
    AND TO_CHAR(shipped_date, 'HH24') <= 19
    AND CLIENT_ID='*****' AND creation_date > sysdate -7
           GROUP BY ORDER_TYPE, TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')
    ORDER BY TO_CHAR(CREATION_DATE, 'DD/MM/YYYY')

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

Буду признателен за любую помощь.

1 Ответ

1 голос
/ 15 июня 2019

Как насчет использования CTE?Примерно так (я удалил большую часть кода, который вы использовали для этих запросов, чтобы упростить его):

with 
  pre_5 as
    (select count(Order_id) as pre_5, 
            type,
            creation_date
     from ...
    ),
  after_5 as
    (select count(order_id) as after_5,
            type,
            creation_date
     from ...
    ),
  same_day as
    (select count(order_id) as same_day,
            type,
            creation_date
     from ...
    )
select
  p.creation_date,
  p.type,
  sum(p.pre_5)    pre_5,
  sum(a.after_5)  after_5,
  sum(s.same_day) same_day
from pre_5 p join after_5  a on a.creation_date = p.creation_date
                            and a.type = p.type
             join same_day s on s.creation_date = p.creation_date
                            and s.type = p.type
group by p.creation_date,
         p.type;
...