Заполните пропущенные месяцы в запросе SELECT - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь заполнить пропущенные месяцы в запросе SELECT. Это выглядит так:

SELECT sl.loonperiode_dt, (sum(slr.uren)) code_220
FROM HR.soc_loonbrief_regels slr,
             HR.soc_loonbrieven sl,
             HR.werknemers w,
             HR.v_kontrakten vk 
WHERE sl.loonperiode_dt BETWEEN '01012018' AND '01122018'
         AND slr.loon_code_id IN (394)
         AND slr.loonbrief_id = sl.loonbrief_id
         AND w.werknemer_id   = sl.werknemer_id
         AND w.werknemer_id   = vk.werknemer_id
         AND vk.functie_id    IN (121, 122, 128)
         AND sl.loonperiode_dt BETWEEN hist_start_dt AND last_day(nvl(hist_eind_dt, sl.loonperiode_dt))
         AND w.afdeling_id  like '961'
GROUP BY sl.loonperiode_dt
ORDER BY sl.loonperiode_dt

Выводит эту таблицу:

31/01/18    234
30/04/18    245,8
31/05/18    714,6
31/07/18    288,04
31/08/18    281
30/11/18    515,12

Я, очевидно, хотел бы, чтобы это было так:

31/01/18    234
28/02/18    0
31/03/18    0
30/04/18    245,8
31/05/18    714,6
30/06/18    0
31/07/18    288,04
31/08/18    281
30/09/18    0
31/10/18    0
30/11/18    515,12
31/12/18    0

У меня есть таблица календаря ' CONV_HC.calendar ' с датами в столбце с именем ' DAT '. Я видел много вопросов и ответов по этому поводу, но я не могу понять, как применить метод LEFT JOIN или любой другой к моей текущей проблеме.

Заранее большое спасибо,

1 Ответ

1 голос
/ 28 марта 2019

Вы можете иметь уже готовую таблицу с месяцами и «соединяться» с ней, группировать по дате, или вы можете создать таблицу с подзапросом или использовать оператор с , что-то вроде

WITH Months (month) AS (
  SELECT 1 AS Month FROM DUAL

  UNION ALL

  SELECT MONTH + 1
  FROM Months
  WHERE MONTH < 12
)
SELECT *
FROM Months

    LEFT JOIN SomeTable
    ON SomeTable.month = Months.MONTH
    --ON Extract(MONTH FROM SomeTable.date) = Months.MONTH

edit

Лучший пример:

--Just to simulate some table data
WITH SomeData AS (
  SELECT TO_DATE('01/01/2019', 'MM/DD/YYYY') AS Dat, 5 AS Value FROM dual
  UNION ALL
  SELECT TO_DATE('01/05/2019', 'MM/DD/YYYY') AS Dat, 7 AS Value FROM dual
  UNION ALL
  SELECT TO_DATE('03/03/2019', 'MM/DD/YYYY') AS Dat, 2 AS Value FROM dual
  UNION ALL
  SELECT TO_DATE('11/05/2019', 'MM/DD/YYYY') AS Dat, 9 AS Value FROM dual
)
, Months (StartDate, MaxYear) AS (
  SELECT CAST(TO_DATE('01/01/2019', 'MM/DD/YYYY') AS DATE) AS StartDate, 2019 AS MaxYear FROM DUAL

  UNION ALL

  SELECT CAST(ADD_MONTHS(StartDate, 1) AS DATE), MaxYear
  FROM Months
  WHERE EXTRACT(YEAR FROM ADD_MONTHS(StartDate, 1)) <= MaxYear 
)
SELECT
    Months.StartDate AS Dat
    , SUM(SomeData.Value) AS SumValue 
FROM Months

    LEFT JOIN SomeData
    ON Extract(MONTH FROM SomeData.Dat) = Extract(MONTH FROM Months.StartDate)

GROUP BY 
    Months.StartDate

edit

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

Давайте попробуем это.Вы можете «добавить» пропущенные месяцы в приложении или присоединиться к нему с уже готовой таблицей, не обязательно быть реальной таблицей, вы можете создать ее.Оператор с является примером этого.Итак, давайте получим весь месяц в последний день 2019 года:

--Geting the last day of every month for 2019
WITH Months (CurrentMonth, MaxYear) AS (
  SELECT CAST(TO_DATE('01/01/2019', 'MM/DD/YYYY') AS DATE) AS CurrentMonth, 2019 AS MaxYear FROM DUAL

  UNION ALL

  SELECT CAST(ADD_MONTHS(CurrentMonth, 1) AS DATE), MaxYear
  FROM Months
  WHERE EXTRACT(YEAR FROM ADD_MONTHS(CurrentMonth, 1)) <= MaxYear  
)
SELECT LAST_DAY(Months.CurrentMonth) AS LastDay
FROM Months

Хорошо, теперь у нас есть все месяцы, доступные для объединения.В вашем запросе у вас уже есть сумма, поэтому давайте пропустим сумму и просто используем ваши данные.Просто добавьте еще один с запросом.

--Geting the last day of every month for 2018
WITH Months (CurrentMonth, MaxYear) AS (
  SELECT CAST(TO_DATE('01/01/2018', 'MM/DD/YYYY') AS DATE) AS CurrentMonth, 2018 AS MaxYear FROM DUAL

  UNION ALL

  SELECT CAST(ADD_MONTHS(CurrentMonth, 1) AS DATE), MaxYear
  FROM Months
  WHERE EXTRACT(YEAR FROM ADD_MONTHS(CurrentMonth, 1)) <= MaxYear  
)
, YourData as (
    SELECT sl.loonperiode_dt, (sum(slr.uren)) code_220
    FROM HR.soc_loonbrief_regels slr,
                 HR.soc_loonbrieven sl,
                 HR.werknemers w,
                 HR.v_kontrakten vk 
    WHERE sl.loonperiode_dt BETWEEN '01012018' AND '01122018'
             AND slr.loon_code_id IN (394)
             AND slr.loonbrief_id = sl.loonbrief_id
             AND w.werknemer_id   = sl.werknemer_id
             AND w.werknemer_id   = vk.werknemer_id
             AND vk.functie_id    IN (121, 122, 128)
             AND sl.loonperiode_dt BETWEEN hist_start_dt AND last_day(nvl(hist_eind_dt, sl.loonperiode_dt))
             AND w.afdeling_id  like '961'
    GROUP BY sl.loonperiode_dt
    --ORDER BY sl.loonperiode_dt
)
SELECT
    LAST_DAY(Months.CurrentMonth) AS LastDay
    , COALESCE(YourData.code_220, 0) AS code_220
FROM Months

    Left Join YourData
    on Extract(MONTH FROM Months.CurrentMonth) = Extract(MONTH FROM YourData.loonperiode_dt)
    --If you have more years: AND Extract(YEAR FROM Months.CurrentMonth) = Extract(YEAR FROM YourData.loonperiode_dt)

ORDER BY LastDay ASC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...