示例数据
Name StartDate Event
Ali 1/7/2010 garage
Ali 1/8/2010 garage
Ali 1/9/2010 garage
Ali 1/10/2010 aircond
Ali 1/11/2010 aircond
Ali 1/12/2010 aircond
Ali 1/13/2010 aircond
Ali 1/14/2010 garage
Ali 1/15/2010 yard
Ali 1/16/2010 dock
Ali 1/17/2010 dock
预期
Name Start Date Event
Ali 1/7/2010 garage
Ali 1/10/2010 aircond
Ali 1/14/2010 garage
Ali 1/15/2010 yard
Ali 1/16/2010 dock
尊敬的专家,
我有一个问题。我需要设计一个查询,这样只有在事件列中有更改时才能获取查询,就像我在预期的表中所做的那样。你能告诉我如何在sql oracle中执行此操作吗?
答案 0 :(得分:2)
Alex Poole的LAG查询的简化版本:
select name, startdate, event
from
(
select name, startdate, event,
case
when event =
lag(event) over (partition by name order by startdate)
then 0 --same event
else 1 --different event or no previous event
end as flag
from t42
)
where flag = 1
order by name, startdate, event;
答案 1 :(得分:1)
这是一个“差距和岛屿”问题。
您可以使用子查询和lag
分析函数来回顾之前的值 - 您可以在其中定义'{1}}和partition by
子句中'previous'的含义 - 然后过滤基于:
order by
SQL Fiddle;或with the intermediate steps所以你可以看到发生了什么。最里面的查询添加了“滞后”列;下一层输出将当前值与滞后值进行比较,只有在它发生变化时才保留;并且外部查询排除那些在该过程之后为空的查询 - 也就是说,它排除那些未更改的那些。
解决此类问题的另一种方法是将每个连续的值运行分配给存储桶,然后查找每个存储桶的第一个日期。您可以使用select name, startdate, event
from (
select name, startdate,
case when lag_event is null or lag_event != event then event end as event
from (
select name, startdate, event,
lag(event) over (partition by name order by startdate) as lag_event
from t42
)
)
where event is not null
order by name, startdate, event;
NAME STARTDATE EVENT
---------- --------- ----------
Ali 07-JAN-10 garage
Ali 10-JAN-10 aircond
Ali 14-JAN-10 garage
Ali 15-JAN-10 yard
Ali 16-JAN-10 dock
分析函数为磁盘分配技巧:
row_number
然后将其用作子查询,使用聚合来获得您感兴趣的第一个日期:
select name, startdate, event,
row_number() over (partition by name, event order by startdate)
- row_number() over (partition by name order by startdate) as chain
from t42
order by name, startdate, event;