Как отфильтровать данные истории на основе самой последней записи? - PullRequest
0 голосов
/ 11 сентября 2018
Table: HISTORY
CUSTOMER    MONTH    PLAN
1           1        A
1           2        A
1           2        B
1           3        B

В этом примере у клиента 1 был план A, и он изменился на B в месяце 2. Мне нужно удалить изменение с месяца 2 и оставить только тот план, с которого клиент перейдет на , например:

CUSTOMER    MONTH    PLAN
1           1        A
1           2        B
1           3        B

Я пытался использовать sys_connect_by_path:

select month, CUSTOMER, level, 
sys_connect_by_path(PLAN, '/') as path
from a
start with month = 1
connect by prior MONTH = MONTH - 1

Но, похоже, это не правильно. Какой эффективный способ сделать это в Oracle 12c?

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Вы можете использовать аналитический lead() вызов, чтобы посмотреть в следующем месяце и решить, использовать ли план на текущий или следующий месяц:

-- CTE for your sample data
with history (customer, month, plan) as (
            select 1, 1, 'A' from dual
  union all select 1, 2, 'A' from dual
  union all select 1, 2, 'B' from dual
  union all select 1, 3, 'B' from dual
)
-- actual query
select distinct customer, month,
  case
    when lead(plan) over (partition by customer order by month) != plan
    then lead(plan) over (partition by customer order by month)
    else plan
  end as plan
from history;

  CUSTOMER      MONTH P
---------- ---------- -
         1          1 A
         1          2 B
         1          3 B

. Вы можете переместить расчет lead() ввстроенное представление, чтобы уменьшить количество повторений, если вы предпочитаете.

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

0 голосов
/ 11 сентября 2018

Я не уверен, что вы поняли, что сказали комментарии - это строки 2 и 3, сомнительные , потому что нет способа узнать, какой из них произошел первым.

В любом случае, как вы сказали, что в этой таблице больше нет ничего, что помогло бы нам решить, как насчет чего-то подобного? Сравните текущий план со следующим (отсортировано по месяцам) и выберите строки, в которых нет изменений в плане.

SQL> with test (customer, month, plan) as
  2    (select 1, 1, 'A' from dual union all
  3     select 1, 2, 'A' from dual union all
  4     select 1, 2, 'B' from dual union all
  5     select 1, 3, 'B' from dual
  6    ),
  7  inter as
  8    (select customer, month, plan,
  9       nvl(lead(plan) over (partition by customer order by month), plan) lead_plan
 10     from test
 11    )
 12  select customer, month, plan
 13  from inter
 14  where plan = lead_plan
 15  order by month;

  CUSTOMER      MONTH PLAN
---------- ---------- -----
         1          1 A
         1          2 B
         1          3 B

SQL>
...