我必须编写一个查询来查找3个或更多连续出现的值(引用列标志),它必须在连续的日期发生。如果连续日期没有发生,查询不应该选择值例如
COLUMN ID DATE FLAG
100 10-JUL-2015 Y
100 11-JUL-2015 Y
100 12-JUL-2015 Y
100 13-JUL-2015 N
100 14-JUL-2015 Y
100 15-JUL-2015 Y
100 16-JUL-2015 N
100 17-JUL-2015 Y
100 18-JUL-2015 Y
100 19-JUL-2015 Y
100 20-JUL-2015 Y
100 21-JUL-2015 Y
输出
COLUMN ID DATE FLAG
100 10-JUL-2015 Y
100 11-JUL-2015 Y
100 12-JUL-2015 Y
100 17-JUL-2015 Y
100 18-JUL-2015 Y
100 19-JUL-2015 Y
100 20-JUL-2015 Y
100 21-JUL-2015 Y
在Oracle SQL中完成此任务的任何想法。我正在尝试使用像LAG和LEAD这样的分析函数,但却无法实现这一目标。
答案 0 :(得分:2)
你可以用一个非常方便的技巧来做到这一点。可以使用row_number()
s的差来计算连续值组。然后,您需要获取每个组的计数并选择符合您条件的组:
select t.*
from (select t.*, count(*) over (partition by id, flag, grp) as cnt
from (select t.*,
(row_number() over (partition by id order by date) -
row_number() over (partition by id, flag order by date)
) as grp
from table t
) t
) t
where cnt >= 3;
严格来说,您不需要row_numbers()
的差异。假设您的日期没有时间组件,以下内容也足够了:
select t.*
from (select t.*, count(*) over (partition by id, flag, grp) as cnt
from (select t.*,
(date -
row_number() over (partition by id, flag order by date)
) as grp
from table t
) t
) t
where cnt >= 3;
答案 1 :(得分:0)
你可以试试这个。这使用了递归公用表表达式和lead
分析函数。
with x as
(select id, mydate, flag from table1 where flag = 'Y')
, y as(select id, mydate, lead(mydate) over(order by mydate) as nxt,flag from x)
, z as (select id, mydate, nxt, lead(nxt) over(order by nxt) as nxt_1,flag from y)
select distinct t.id, t.mydate,t.flag from z
join x t on z.id = t.id
and (t.mydate = z.mydate or t.mydate = z.nxt or t.mydate = z.nxt_1)
where z.nxt-z.mydate = 1 and z.nxt_1-z.nxt =1
order by t.mydate
SQL测试数据 :http://sqlfiddle.com/#!4/9bbed/1