oracle запрос на предоставление данных только за 1 или 2 полугодие - PullRequest
1 голос
/ 24 апреля 2020

У меня есть отчет, который должен отображать данные о регистрации только в двух диапазонах дат январь-июнь или июль-де c в зависимости от текущей даты. Scenar ios:

  • Если текущая дата 042020, то я должен отображать данные о регистрации между этим диапазоном: 072019-122019
  • Если текущая дата 072020, тогда я должен отображать регистрацию данные в этом диапазоне: 012020-062020
  • Если текущая дата - 022021, то я должен отобразить данные регистрации в этом диапазоне: 072020-122020

Текущий запрос сообщает обо всех событиях за последние 6 месяцев с его запрос.

select * from enrollement where enrollement_dt > add_months(sysdate - 6);

Есть ли в oracle какая-либо функция, позволяющая сделать то же самое, или как мне получить logi c в одном выражении?

Любая помощь с этим высоко ценится.

Ответы [ 3 ]

1 голос
/ 24 апреля 2020

Вы можете попробовать запрос ниже -

select *
from enrollement
WHERE TO_CHAR(enrollement_dt, 'MMYYYY') >= CASE WHEN TO_CHAR(SYSDATE, 'mm') <= '06'
                                                          THEN TO_DATE('07' || EXTRACT(YEAR FROM SYSDATE) - 1, 'MMYYYY') 
                                                ELSE THEN TO_DATE('01' || EXTRACT(YEAR FROM SYSDATE), 'MMYYYY')
                                           END
  AND TO_CHAR(enrollement_dt, 'MMYYYY') <= CASE WHEN TO_CHAR(SYSDATE, 'mm') <= '06'
                                                          THEN TO_DATE('12' || EXTRACT(YEAR FROM SYSDATE) - 1, 'MMYYYY') 
                                                ELSE THEN TO_DATE('06' || EXTRACT(YEAR FROM SYSDATE), 'MMYYYY')
                                           END
1 голос
/ 25 апреля 2020

В основном вы хотите урезать до полугода. Но Oracle не поддерживает это.

Один метод считает полугодия и сравнивает их. Вы хотите предыдущее полугодие с текущей даты. Это будет:

select (extract(year from sysdate) * 2 + floor(extract(month from sysdate) - 1) / 6) - 1
from dual

Вы можете использовать эту же формулу:

where (extract(year from enrollement_dt) * 2 + floor(extract(month from enrollement_dt) - 1) / 6) - 1 =
       extract(year from sysdate) * 2 + floor(extract(month from sysdate) - 1) / 6) - 1
      )

from dual;

К сожалению, не может использовать индекс для столбца. Итак, мы можем вернуться к этому. Вы можете получить первый день текущей половины, используя некоторую арифметику даты c:

select trunc(sysdate, 'Q') - mod(floor((extract(month from sysdate) - 1) / 3), 2) * interval '3' month
from dual

, которая просто должна быть включена в предложение where:

where enrollement_dt >= trunc(sysdate, 'Q') - mod(floor((extract(month from sysdate) - 1) / 3), 2) * interval '3' month - interval '6' month and
      enrollement_dt < trunc(sysdate, 'Q') - mod(floor((extract(month from sysdate) - 1) / 3), 2) * interval '3' month

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

1 голос
/ 24 апреля 2020

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

        WITH data
         AS (SELECT TRUNC(SYSDATE) curr_date from dual
             ),
         d2
         AS (SELECT curr_date,
                    To_date('0107'
                            ||( Extract (year FROM curr_date) - 1 ), 'ddmmyyyy')
                       start_first_half,
                    To_date('3112'
                            ||( Extract (year FROM curr_date) - 1 ), 'ddmmyyyy')
                       end_first_half,
                    To_date('0101'
                            ||Extract (year FROM curr_date), 'ddmmyyyy')
                       start_second_half,
                    To_date('3006'
                            ||Extract (year FROM curr_date), 'ddmmyyyy')
                       end_second_half
             FROM   data)
    SELECT curr_date,
           CASE
             WHEN To_char(curr_date, 'MM') >= To_char(start_first_half, 'MM')
                  AND To_char(curr_date, 'MM') <= To_char(end_first_half, 'MM') THEN
             start_second_half
             ELSE start_first_half
           END start_date1,
           CASE
             WHEN To_char(curr_date, 'MM') >= To_char(start_first_half, 'MM')
                  AND To_char(curr_date, 'MM') <= To_char(end_first_half, 'MM') THEN
             end_second_half
             ELSE end_first_half
           END end_date1
    FROM   d2 

Вы можете использовать его в вашем запросе, как показано ниже

  Select * from enrollment_table a, (WITH data
     AS (SELECT TRUNC(SYSDATE) curr_date from dual
         ),
     d2
     AS (SELECT curr_date,
                To_date('0107'
                        ||( Extract (year FROM curr_date) - 1 ), 'ddmmyyyy')
                   start_first_half,
                To_date('3112'
                        ||( Extract (year FROM curr_date) - 1 ), 'ddmmyyyy')
                   end_first_half,
                To_date('0101'
                        ||Extract (year FROM curr_date), 'ddmmyyyy')
                   start_second_half,
                To_date('3006'
                        ||Extract (year FROM curr_date), 'ddmmyyyy')
                   end_second_half
         FROM   data)
SELECT curr_date,
       CASE
         WHEN To_char(curr_date, 'MM') >= To_char(start_first_half, 'MM')
              AND To_char(curr_date, 'MM') <= To_char(end_first_half, 'MM') THEN
         start_second_half
         ELSE start_first_half
       END start_date1,
       CASE
         WHEN To_char(curr_date, 'MM') >= To_char(start_first_half, 'MM')
              AND To_char(curr_date, 'MM') <= To_char(end_first_half, 'MM') THEN
         end_second_half
         ELSE end_first_half
       END end_date1
FROM   d2 ) b
where a.enrollment_date >=b.start_date1
and a.enrollment_date <=b.end_date1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...