如何根据最近的记录过滤历史数据?
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()
计算移动到内联视图中以减少重复。
如果客户连续几个月更改计划,或者他们可以在一个月内更改多次,这可能会以有趣的方式中断。
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()
计算移动到内联视图中以减少重复。
如果客户连续几个月更改计划,或者他们可以在一个月内更改多次,这可能会以有趣的方式中断。