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

how to filter history data based on most recent record?

Table: HISTORY
CUSTOMER    MONTH    PLAN
1           1        A
1           2        A
1           2        B
1           3        B

在此示例中,客户 1 有计划 A 并在 2 月更改为 B。我需要删除 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 行和第 3 行有疑问,因为无法知道其中哪一个先发生。

无论如何,正如您所说 table 中没有其他任何东西可以帮助我们做出决定,这样的事情怎么样?将当前计划与下一个计划进行比较(按月排序)并选择计划没有变化的行。

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>

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

如果客户连续几个月更改计划,或者他们可以在一个月内更改多次,这可能会以有趣的方式中断。