Минимум три месяца между созданными номерами дел для уникальных номеров полисов - PullRequest
0 голосов
/ 08 мая 2019

У меня есть таблица с тремя столбцами, policy_no, casenumber, creation_date; для одной и той же уникальной политики можно создать несколько разных номеров дел. Мне нужно просмотреть все данные из таблицы, за исключением тех случаев, когда между последним созданным номером дела и любым, созданным до этого, существует разрыв менее трех месяцев. Так, например, если номер дела был создан для номера политики 1 июля, но до этого были также созданы номера дел для того же номера политики 15 июня и 1 мая, я хочу только просмотреть данные для номер дела, который был создан 1 июля, потому что я хочу посчитать этот уникальный номер политики только один раз. Однако, если разрыв превышает три месяца, например, когда номер дела был создан 1 июля, а последний, созданный до этого, был создан 30 апреля, тогда я хочу включить оба этих случая и иметь счет 2 для этот уникальный номер политики.

Надеюсь, все это имеет смысл! Не уверен, с чего начать!

Ответы [ 2 ]

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

Во-первых, вы должны знать, что month не является точной единицей времени. Здесь я использовал функцию Oracle months_between, но вы также можете вычесть даты и сравнить их с 30. Months_between может дать результаты, которые не являются интуитивными, но они верны. Например:

select months_between(date '2019-03-29', date '2019-02-28') from dual;

select months_between(date '2019-03-31', date '2019-02-28') from dual;

Первый выбор дает 1.03, второй дает 1. Странно, но логично. Это потому, что месяц не является точной единицей.

Вы предупреждены :) Теперь решение. Сначала мои образцы данных, 3 различных номера политики с различными случаями:

create table policies(policy_no, casenumber, created_date) as (
    select 1, 101, date '2007-01-01' from dual union all
    select 1, 102, date '2007-02-01' from dual union all
    select 1, 103, date '2007-06-01' from dual union all
    select 1, 104, date '2007-09-15' from dual union all
    select 1, 105, date '2007-11-01' from dual union all    
    select 1, 106, date '2007-12-01' from dual union all
    select 2, 201, date '1992-08-30' from dual union all
    select 3, 301, date '1995-07-12' from dual union all
    select 3, 302, date '1995-08-30' from dual union all
    select 3, 303, date '1997-02-25' from dual );

И мой запрос:

with 
    t(pn, cn, cdt, rn) as (
      select policy_no, casenumber, created_date, 
             row_number() over (partition by policy_no order by created_date desc) 
        from policies),
    c(pn, cn, cdt, rn, diff, ldt, info) as (
      select pn, cn, cdt, 1, 0, cdt,  'last' from t where rn = 1
      union all 
      select t.pn, t.cn, t.cdt, t.rn, round(months_between(c.ldt, t.cdt), 2),
             case when months_between(c.ldt, t.cdt) >= 3 then t.cdt else c.ldt end,
             case when months_between(c.ldt, t.cdt) >= 3 then 'inlcuded' else 'excluded' end
        from c join t on t.pn = c.pn and t.rn = c.rn + 1)
select * from c order by pn, rn

Результат:

        PN         CN CDT                 RN       DIFF LDT         INFO
---------- ---------- ----------- ---------- ---------- ----------- --------
         1        106 2007-12-01           1          0 2007-12-01  last
         1        105 2007-11-01           2          1 2007-12-01  excluded
         1        104 2007-09-15           3       2,55 2007-12-01  excluded
         1        103 2007-06-01           4          6 2007-06-01  inlcuded
         1        102 2007-02-01           5          4 2007-02-01  inlcuded
         1        101 2007-01-01           6          1 2007-02-01  excluded
         2        201 1992-08-30           1          0 1992-08-30  last
         3        303 1997-02-25           1          0 1997-02-25  last
         3        302 1995-08-30           2      17,84 1995-08-30  inlcuded
         3        301 1995-07-12           3       1,58 1995-08-30  excluded

Вас интересуют только строки с информацией last или included.

Как это работает? Подзапрос t только добавляет нумерацию к строкам, она для каждой политики разделяется, самый новый случай - первый. Подзапрос c является основной частью решения. Это рекурсивно. Мы начинаем с номеров строк 1, и на каждом следующем шаге мы ищем следующий номер строки и проверяем, не старше ли его дата, чем три месяца после запоминания. Если это так, мы сохраняем его (в столбце ldt), если нет, используется предыдущий.

Вот так работает рекурсивный запрос. Надеюсь, я правильно понял. Если вам нужно проверять только между соседними строками, тогда функции lag или lead будет достаточно, но здесь вам нужна рекурсия.

Надеюсь, это поможет и извините за любые языковые ошибки:)

0 голосов
/ 08 мая 2019

В приведенном ниже запросе вы получите запись для поступивших политик, с интервалом более 3 месяцев. 90 дней.

SELECT A.POLICY_NO,
       A.CASENUMBER,
       A.CREATED_DATE,
       B.CASENUMBER,
       B.CREATED_DATE
  FROM POLICY_CASES A, POLICY_CASES B
 WHERE     A.POLICY_NO = B.A.POLICY_NO
       AND A.CASENUMBER <> B.CASENUMBER
       AND B.CREATED_DATE > A.CREATED_DATE
       AND (B.CREATED_DATE - A.CREATED_DATE) > 90
       order by 1,3,5

требуется еще несколько данных, например, если поднятый случай уже решен. включить это или только включить ожидающие дела. или вы хотите только последний и второй последний и т. д.

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