Как получить ежемесячный счет между двумя идентификаторами даты в Oracle - PullRequest
0 голосов
/ 07 января 2020

Я хочу получать ежемесячные подсчеты между двумя датами. Например, возьмем следующий диапазон:

20181202 - 20190202

Этот диапазон даст +1 к счетам «декабрь» для 2018 года и «январь», «февраль» для 2019 года.

В настоящее время я агрегирую по месяцам и годам, чтобы получить эти значения, но я забыл о случае, когда между датами существует разрыв более 1 года.

Запрос сейчас выглядит примерно так это:

    CREATE VIEW V_A_A AS
SELECT CASE WHEN 01>=JT.SUBSTR(START,5,2) AND 01<=JT.SUBSTR(ENDID,1,4) THEN 'JAN'
WHEN 02>=JT.SUBSTR(START,5,2) AND 02<=JT.SUBSTR(ENDID,5,2) THEN 'FEB'
WHEN 03>=JT.SUBSTR(START,5,2) AND 03<=JT.SUBSTR(ENDID,5,2) THEN 'MAR'
WHEN 04>=JT.SUBSTR(START,5,2) AND 04<=JT.SUBSTR(ENDID,5,2) THEN 'APR'
WHEN 05>=JT.SUBSTR(START,5,2) AND 05<=JT.SUBSTR(ENDID,5,2) THEN 'MAY'
WHEN 06>=JT.SUBSTR(START,5,2) AND 06<=JT.SUBSTR(ENDID,5,2) THEN 'JUNE'
WHEN 07>=JT.SUBSTR(START,5,2) AND 07<=JT.SUBSTR(ENDID,5,2) THEN 'JULY'
WHEN 08>=JT.SUBSTR(START,5,2) AND 08<=JT.SUBSTR(ENDID,5,2) THEN 'AUG'
WHEN 09>=JT.SUBSTR(START,5,2) AND 09<=JT.SUBSTR(ENDID,5,2) THEN 'SEPT'
WHEN 10>=JT.SUBSTR(START,5,2) AND 10<=JT.SUBSTR(ENDID,5,2) THEN 'OCT'
WHEN 11>=JT.SUBSTR(START,5,2) AND 11<=JT.SUBSTR(ENDID,5,2) THEN 'NOV'
WHEN 12>=JT.SUBSTR(START,5,2) AND 12<=JT.SUBSTR(ENDID,5,2) THEN 'DEC' ELSE 'N/A' END MONTH
,CASE WHEN 2019>=JT.SUBSTR(START,1,4) AND 2019<=JT.SUBSTR(ENDID,1,4) THEN 2019 
WHEN 2018>=JT.SUBSTR(START,1,4) AND 2018<=JT.SUBSTR(ENDID,1,4) THEN 2018
WHEN 2017>=JT.SUBSTR(START,1,4) AND 2017<=JT.SUBSTR(ENDID,1,4) THEN 2017
WHEN 2016>=JT.SUBSTR(START,1,4) AND 2016<=JT.SUBSTR(ENDID,1,4) THEN 2016
WHEN 2015>=JT.SUBSTR(START,1,4) AND 2015<=JT.SUBSTR(ENDID,1,4) THEN 2015 ELSE 0 END YEAR
,COUNT(*) AS COUNT
from 
(select * from some_db a
INNER JOIN another_db b ON a.field = b.field
WHERE a.name = "Private" JT 
GROUP BY CASE WHEN 2019>=JT.SUBSTR(START,1,4) AND 2019<=JT.SUBSTR(ENDID,1,4) THEN 2019 
WHEN 2018>=JT.SUBSTR(START,1,4) AND 2018<=JT.SUBSTR(ENDID,1,4) THEN 2018
WHEN 2017>=JT.SUBSTR(START,1,4) AND 2017<=JT.SUBSTR(ENDID,1,4) THEN 2017
WHEN 2016>=JT.SUBSTR(START,1,4) AND 2016<=JT.SUBSTR(ENDID,1,4) THEN 2016
WHEN 2015>=JT.SUBSTR(START,1,4) AND 2015<=JT.SUBSTR(ENDID,1,4) THEN 2015 ELSE 0 END,
CASE WHEN 01>=JT.SUBSTR(START,5,2) AND 01<=JT.SUBSTR(ENDID,1,4) THEN 'JAN'
WHEN 02>=JT.SUBSTR(START,5,2) AND 02<=JT.SUBSTR(ENDID,5,2) THEN 'FEB'
WHEN 03>=JT.SUBSTR(START,5,2) AND 03<=JT.SUBSTR(ENDID,5,2) THEN 'MAR'
WHEN 04>=JT.SUBSTR(START,5,2) AND 04<=JT.SUBSTR(ENDID,5,2) THEN 'APR'
WHEN 05>=JT.SUBSTR(START,5,2) AND 05<=JT.SUBSTR(ENDID,5,2) THEN 'MAY'
WHEN 06>=JT.SUBSTR(START,5,2) AND 06<=JT.SUBSTR(ENDID,5,2) THEN 'JUNE'
WHEN 07>=JT.SUBSTR(START,5,2) AND 07<=JT.SUBSTR(ENDID,5,2) THEN 'JULY'
WHEN 08>=JT.SUBSTR(START,5,2) AND 08<=JT.SUBSTR(ENDID,5,2) THEN 'AUG'
WHEN 09>=JT.SUBSTR(START,5,2) AND 09<=JT.SUBSTR(ENDID,5,2) THEN 'SEPT'
WHEN 10>=JT.SUBSTR(START,5,2) AND 10<=JT.SUBSTR(ENDID,5,2) THEN 'OCT'
WHEN 11>=JT.SUBSTR(START,5,2) AND 11<=JT.SUBSTR(ENDID,5,2) THEN 'NOV'
WHEN 12>=JT.SUBSTR(START,5,2) AND 12<=JT.SUBSTR(ENDID,5,2) THEN 'DEC' ELSE 'N/A' END

1 Ответ

1 голос
/ 07 января 2020

Насколько я понимаю, вам нужны целые годы граничных дат (в данном случае 2018 - 2019). Поэтому должно быть 24 ряда. И если эти 24 месяца совпадают с месяцами интервала между граничными датами, то вам необходим счетчик один, иначе ноль. Итак, рассмотрим:

SELECT SUBSTR(t1.months,1,4) as "Year", 
       TO_CHAR( TO_DATE(t1.months,'yyyymm'), 'Month' ) as "Month",
       NVL2(t2.months,1,0) as "Count"
  FROM
  (
SELECT y.years||m.months as months
  FROM
  (
   SELECT DISTINCT TO_CHAR(ADD_MONTHS( TO_DATE('20181202','yyyymmdd') , level - 1 ),'yyyy')
          as years
     FROM dual
  CONNECT BY level <= 
    MONTHS_BETWEEN(TO_DATE('20190202','yyyymmdd'),TO_DATE('20181202','yyyymmdd')) + 1 ) y
   CROSS JOIN
   (
    SELECT LPAD(LEVEL,2,'0') months
      FROM dual
   CONNECT BY level <= 12
   ) m
  ) t1
 LEFT JOIN
 (
    SELECT TO_CHAR(ADD_MONTHS( TO_DATE('20181202','yyyymmdd') , level - 1 ),'yyyymm')
          as months
     FROM dual
  CONNECT BY level <= 
      MONTHS_BETWEEN(TO_DATE('20190202','yyyymmdd'),TO_DATE('20181202','yyyymmdd')) + 1
 ) t2
 ON t1.months = t2.months
 ORDER BY t1.months

, где CROSS JOIN, а затем LEFT JOIN рекурсивно.

Демо

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