如何根据最新记录过滤历史数据?

时间:2018-09-11 16:47:34

标签: oracle oracle12c connect-by

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 :(得分:1)

我不确定您是否理解评论的内容-第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>

答案 1 :(得分:0)

您可以使用分析型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()计算移到嵌入式视图中以减少重复。

但是,如果客户连续几个月更改计划,或者一个月内可以更改一次以上,则可能会以有趣的方式中断。