Рекурсивный запрос Sql Oracle 3 месяца разница между датами - PullRequest
0 голосов
/ 10 мая 2019

У меня есть простая таблица с тремя столбцами, policy_no, casenumber и creation_date. Несколько регистрационных номеров могут быть зарегистрированы против уникальных номеров политики. Мне нужен запрос, который проходит через данные, находит самый ранний случай для политики, а затем проверяет разницу между этим и следующим. Если разница превышает три месяца, она включает первый случай, если разница короче, она исключает первый случай, а затем переходит ко второму случаю и снова проверяет разницу между этим и третьим случаем. По сути, я хочу включить только те дела, которые не были подняты в течение следующих трех месяцев.

Select * from policy_table
where policy_no = '17850850'

Вернет следующие результаты;

policy_no   casenumber  created_date
17850850    4150778     16-APR-19
17850850    3955549     22-JAN-19
17850850    3188447     14-MAY-18
17850850    2998931     14-MAR-18
17850850    2767545     29-DEC-17
17850850    2420594     05-SEP-17

Первый случай, поднятый 05/09/2017, должен быть включен, поскольку до 29.12.2017 (больше 3 месяцев) больше не было никаких дел. Дело, возбужденное 29.12.2017, следует исключить, так как дело было возбуждено 14/03/2018. Дело, возбужденное 14/03/2018, также должно быть исключено, поскольку другое дело было возбуждено 14/05/2018 (в течение 3 месяцев). Случай, поднятый 14/05/2018, должен быть включен, 22/01/2019 должен быть исключен, и 16/04/2019 должен быть временно включен (при условии, что в течение следующих трех месяцев больше не будет возбуждено никаких дел). Любая помощь приветствуется. Глядя, чтобы добраться до этого;

policy_no   casenumber  created_date    Diff    Outcome
17850850    4150778     16-APR-19               latest
17850850    3955549     22-JAN-19       2.8     excluded
17850850    3188447     14-MAY-18       8.3     Included
17850850    2998931     14-MAR-18       2       excluded
17850850    2767545     29-DEC-17       2.5     excluded
17850850    2420594     05-SEP-17       3.77    Included

Ответы [ 2 ]

2 голосов
/ 10 мая 2019

Вам не нужно делать это рекурсивно, вы можете использовать not exists для проверки любых случаев в течение трех месяцев:

-- CTE for sample data
with your_table (policy_no, casenumber, created_date) as (
            select 17850850, 4150778, date '2019-04-16' from dual
  union all select 17850850, 3955549, date '2019-01-22' from dual
  union all select 17850850, 3188447, date '2018-05-14' from dual
  union all select 17850850, 2998931, date '2018-03-14' from dual
  union all select 17850850, 2767545, date '2017-12-29' from dual
  union all select 17850850, 2420594, date '2017-09-17' from dual
)
-- actual query
select policy_no, casenumber, created_date
from your_table t
where policy_no = 17850850
and not exists (
  select *
  from your_table t2
  where t2.policy_no = t.policy_no
  and t2.casenumber != t.casenumber
  and t2.created_date >= t.created_date
  and t2.created_date <= add_months(t.created_date, 3)
)
order by policy_no, created_date desc;

 POLICY_NO CASENUMBER CREATED_DATE
---------- ---------- ------------
  17850850    4150778 2019-04-16  
  17850850    3188447 2018-05-14  
  17850850    2420594 2017-09-17  

Если вы хотите просмотреть все строки с разницей по месяцами последний / исключенный / включенный флаг, как показано в отредактированном вопросе, вместо этого вы можете использовать встроенное представление, чтобы найти следующую созданную дату и разницу, а затем установить флаг на основе этого во внешнем запросе:

-- with same CTE for sample data
select policy_no, casenumber, created_date,
  trunc(diff, 2) as diff,
  case when diff is null then 'latest'
       when diff <= 3 then 'excluded'
       else 'included'
  end as outcome
from (
  select policy_no, casenumber, created_date,
    months_between(lead(created_date) over (partition by policy_no order by created_date),
      created_date) as diff
  from your_table t
)
where policy_no = 17850850
order by policy_no, created_date desc;

 POLICY_NO CASENUMBER CREATED_DATE       DIFF OUTCOME 
---------- ---------- ------------ ---------- --------
  17850850    4150778 2019-04-16              latest  
  17850850    3955549 2019-01-22          2.8 excluded
  17850850    3188447 2018-05-14         8.25 included
  17850850    2998931 2018-03-14            2 excluded
  17850850    2767545 2017-12-29         2.51 excluded
  17850850    2420594 2017-09-17         3.38 included

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

-- with same CTE
select policy_no, casenumber, created_date
from (
  select policy_no, casenumber, created_date,
    months_between(lead(created_date) over (partition by policy_no order by created_date),
      created_date) as diff
  from your_table t
)
where policy_no = 17850850
and (diff is null or diff > 3)
order by policy_no, created_date desc;

 POLICY_NO CASENUMBER CREATED_DATE
---------- ---------- ------------
  17850850    4150778 2019-04-16  
  17850850    3188447 2018-05-14  
  17850850    2420594 2017-09-17  

db <> fiddle

1 голос
/ 10 мая 2019

Используйте аналитическую функцию LAG и MONTHS_BETWEEN:

Установка Oracle :

CREATE TABLE test_data ( policy_no, casenumber, created_date ) AS
SELECT 17850850, 4150778, DATE '2019-04-16' FROM DUAL UNION ALL
SELECT 17850850, 3955549, DATE '2019-01-22' FROM DUAL UNION ALL
SELECT 17850850, 3188447, DATE '2018-05-14' FROM DUAL UNION ALL
SELECT 17850850, 2998931, DATE '2018-03-14' FROM DUAL UNION ALL
SELECT 17850850, 2767545, DATE '2017-12-29' FROM DUAL UNION ALL
SELECT 17850850, 2420594, DATE '2017-09-05' FROM DUAL

Запрос :

SELECT t.*,
       CASE
       WHEN diff IS NULL THEN 'latest'
       WHEN diff <= 3    THEN 'excluded'
                         ELSE 'included'
       END AS outcome
FROM (
  SELECT t.*,
         MONTHS_BETWEEN(
           LAG( created_date ) OVER ( PARTITION BY policy_no ORDER BY created_date DESC ),
           created_date
         ) AS diff
  FROM   test_data t
) t

Выход :

POLICY_NO | CASENUMBER | CREATED_DATE |                                     DIFF | OUTCOME 
--------: | ---------: | :----------- | ---------------------------------------: | :-------
 17850850 |    4150778 | 16-APR-19    |                                     <em>null</em> | latest  
 17850850 |    3955549 | 22-JAN-19    | 2.80645161290322580645161290322580645161 | excluded
 17850850 |    3188447 | 14-MAY-18    | 8.25806451612903225806451612903225806452 | included
 17850850 |    2998931 | 14-MAR-18    |                                        2 | excluded
 17850850 |    2767545 | 29-DEC-17    | 2.51612903225806451612903225806451612903 | excluded
 17850850 |    2420594 | 05-SEP-17    | 3.77419354838709677419354838709677419355 | included

дБ <> скрипка здесь

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