Как отфильтровать записи, которые включают открытые интервалы или заданные c закрытые интервалы с предложением Oracle SQL WHERE? - PullRequest
1 голос
/ 02 апреля 2020

Я использую базу данных oracle и у меня есть следующие таблицы базы данных (формат даты только dd.MM.yyyy):

ID | ACCOUNT_ID    |    BEGINN_DATE     |     END_DATE      |     NO_END_DATE_AVAILABE    |     MAX_END_DATE_QUARTER    |    QUARTER
--------------------------------------------------------------------------------------------------------------------------------------
 1 |      1        |    01.10.2019      |     31.12.2019    |              0              |          31.12.2019         |   01.10.2019
--------------------------------------------------------------------------------------------------------------------------------------
 2 |      1        |    01.01.2020      |     04.01.2020    |              0              |          04.01.2020         |   01.01.2020
--------------------------------------------------------------------------------------------------------------------------------------
 3 |      1        |    05.01.2020      |        NULL       |              1              |          04.01.2020         |   01.01.2020
--------------------------------------------------------------------------------------------------------------------------------------
 4 |      2        |    02.11.2019      |     10.01.2020    |              0              |          25.02.2020         |   01.10.2019
--------------------------------------------------------------------------------------------------------------------------------------
 5 |      2        |    02.11.2019      |     10.01.2010    |              0              |          25.02.2020         |   01.01.2020
--------------------------------------------------------------------------------------------------------------------------------------
 6 |      2        |    11.01.2020      |     25.02.2020    |              0              |          25.02.2020         |   01.01.2020
--------------------------------------------------------------------------------------------------------------------------------------
 7 |      3        |    02.07.2019      |     25.08.2019    |              0              |          30.09.2019         |   01.07.2019
--------------------------------------------------------------------------------------------------------------------------------------
 8 |      3        |    26.08.2019      |     15.09.2019    |              0              |          30.09.2019         |   01.07.2019
--------------------------------------------------------------------------------------------------------------------------------------
 9 |      3        |    16.09.2019      |     30.09.2019    |              0              |          30.09.2019         |   01.07.2019  
--------------------------------------------------------------------------------------------------------------------------------------
10 |      3        |    01.10.2019      |     15.10.2019    |              0              |          15.10.2019         |   01.10.2019
--------------------------------------------------------------------------------------------------------------------------------------
11 |      3        |    16.10.2019      |        NULL       |              1              |          15.10.2019         |   01.10.2019
--------------------------------------------------------------------------------------------------------------------------------------
12 |      4        |    29.09.2019      |     02.10.2019    |              0              |          02.10.2019         |   01.07.2019
--------------------------------------------------------------------------------------------------------------------------------------
13 |      4        |    29.09.2019      |     02.10.2019    |              0              |          02.10.2019         |   01.10.2019
--------------------------------------------------------------------------------------------------------------------------------------
14 |      4        |    03.10.2019      |        NULL       |              1              |          02.10.2019         |   01.10.2019
--------------------------------------------------------------------------------------------------------------------------------------

Столбец BEGINN_DATE и END_DATE представляет интервал значений даты. Значения внутри столбца квартал представляют только первый день квартала, который включается в значение между столбцами BEGINN_DATE и END_DATE .

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

Для каждого квартала Я хочу получить

  • запись, в которой внутри столбца END_DATE существует NULL значение
  • запись, в которой значение столбца представляет MAX Date этого квартала

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

Я хочу получить эти записи для Account_ID 1 :

ID | ACCOUNT_ID    |    BEGINN_DATE     |     END_DATE      |     NO_END_DATE_AVAILABE    |       MAX_END_DATE_QUARTER    |    QUARTER
----------------------------------------------------------------------------------------------------------------------------------------
 1 |      1        |    01.10.2019      |     31.12.2019    |              0              |            31.12.2019         |   01.10.2019
----------------------------------------------------------------------------------------------------------------------------------------
 3 |      1        |    05.01.2020      |        NULL       |              1              |            04.01.2020         |   01.01.2020
----------------------------------------------------------------------------------------------------------------------------------------

Я хочу получить эти записи для Account_ID 2 :

ID | ACCOUNT_ID    |    BEGINN_DATE     |     END_DATE      |     NO_END_DATE_AVAILABE    |       MAX_END_DATE_QUARTER    |    QUARTER
----------------------------------------------------------------------------------------------------------------------------------------
 4 |      2        |    02.11.2019      |     10.01.2020    |              0              |            25.02.2020         |   01.10.2019
----------------------------------------------------------------------------------------------------------------------------------------   
 6 |      2        |    11.01.2020      |     25.02.2020    |              1              |            25.02.2020         |   01.01.2020
----------------------------------------------------------------------------------------------------------------------------------------

Я хочу получить эти записи для Account_ID 3 :

ID | ACCOUNT_ID    |    BEGINN_DATE     |     END_DATE      |     NO_END_DATE_AVAILABE    |      MAX_END_DATE_QUARTER     |    QUARTER
----------------------------------------------------------------------------------------------------------------------------------------
 9 |      3        |    16.09.2019      |     30.09.2019    |              0              |            30.09.2019         |   01.07.2019  
----------------------------------------------------------------------------------------------------------------------------------------
11 |      3        |    16.10.2019      |        NULL       |              1              |            15.10.2019         |   01.10.2019
----------------------------------------------------------------------------------------------------------------------------------------

Я хочу получить эти записи для Account_ID 4 :

ID | ACCOUNT_ID    |    BEGINN_DATE     |     END_DATE      |     NO_END_DATE_AVAILABE    |      MAX_END_DATE_QUARTER     |    QUARTER
----------------------------------------------------------------------------------------------------------------------------------------
12 |      4        |    29.09.2019      |     02.10.2019    |              0              |            02.10.2019         |   01.07.2019
----------------------------------------------------------------------------------------------------------------------------------------
14 |      4        |    03.10.2019      |        NULL       |              1              |            02.10.2019         |   01.10.2019
----------------------------------------------------------------------------------------------------------------------------------------

Я написал SQL WHERE предложение что-то вроде этого

SELECT *
FROM myTable t
WHERE (t.no_end_date_available = 1 AND t.end_date IS NULL) OR
      (t.no_end_date_available = 0 AND t.end_date = t.max_end_date_quarter)

Но это SQL ГДЕ не работает нормально. Для Account_ID 1 я получаю эти записи:

ID | ACCOUNT_ID    |    BEGINN_DATE     |     END_DATE      |     NO_END_DATE_AVAILABE    |     MAX_END_DATE_QUARTER    |    QUARTER
--------------------------------------------------------------------------------------------------------------------------------------
 1 |      1        |    01.10.2019      |     31.12.2019    |              0              |          31.12.2019         |   01.10.2019
--------------------------------------------------------------------------------------------------------------------------------------
 2 |      1        |    01.01.2020      |     04.01.2020    |              0              |          04.01.2020         |   01.01.2020
--------------------------------------------------------------------------------------------------------------------------------------
 3 |      1        |    05.01.2020      |        NULL       |              1              |          04.01.2020         |   01.01.2020
--------------------------------------------------------------------------------------------------------------------------------------

Но я хочу получить эти записи:

ID | ACCOUNT_ID    |    BEGINN_DATE     |     END_DATE      |     NO_END_DATE_AVAILABE    |       MAX_END_DATE_QUARTER    |    QUARTER
----------------------------------------------------------------------------------------------------------------------------------------
 1 |      1        |    01.10.2019      |     31.12.2019    |              0              |            31.12.2019         |   01.10.2019
----------------------------------------------------------------------------------------------------------------------------------------
 3 |      1        |    05.01.2020      |        NULL       |              1              |            04.01.2020         |   01.01.2020
----------------------------------------------------------------------------------------------------------------------------------------

Как я могу решить эту проблему? Большое спасибо за помощь.

1 Ответ

0 голосов
/ 02 апреля 2020

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

SELECT *
FROM (SELECT m.id, 
             m.account_id, 
             m.begin_date,
             m.end_date, 
             m.quarter, 
             MAX(NVL(m.end_date, to_date('31.12.3000', 'DD.MM.YYYY'))) OVER (PARTITION BY m.account_id, m.quarter) AS MAX_DATE
      FROM myTable m) sub
WHERE DECODE(sub.end_date, NULL, 1, sub.max_date, 1, 0) = 1;

Я эффективно пересчитываю ваш MAX_END_DATE_QUARTER, чтобы гарантировать, что значения NULL всегда будут максимальными, путем установки ложной сверхвысокой даты в качестве макс. Затем внешний запрос выбирает только нулевые конечные даты или даты, в которых конечная дата соответствует рассчитанному максимуму.

. Следующий SQLFiddle показывает этот запрос с предоставленными тестовыми данными. ( Ссылка )

...