Oracle SQL-查找连续日期上的连续值

Oracle SQL-查找连续日期上的连续值,sql,oracle,Sql,Oracle,我必须编写一个查询来查找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-20

我必须编写一个查询来查找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中实现这一点的想法。我正在尝试使用滞后和超前等分析函数,但无法实现这一点。

您可以使用非常方便的技巧来实现这一点。连续值组可以使用
row\u 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;
严格地说,您不需要区分
行数()。假设您的日期没有时间成分,以下内容也就足够了:

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;

你可以试试这个。这利用了递归公共表表达式和
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
SQLfiddle处理测试数据

我正试图用
RANK
来做同样的事情。但是我在我的系统中测试了你的代码,但没有运行。也许你想检查一下。@JuanCarlosOropeza。表和列只需要有正确的名称:。我认为这不适用于以下情况:列ID日期标志100 2015年7月10日Y 100 2015年7月11日Y 100 2015年7月12日Y 100 2015年7月15日Y在以下场景中,该查询仍然会获取2015年7月15日的行,并且shouldnt@Sandy . . . 您可以设置SQL小提琴吗?“我认为它在这种情况下是有效的。”@GordonLinoff——事实上,如果我们检查连续的3个日期,它是有效的。连续4次约会怎么样。我使用了4个连续日期的标准来运行相同的程序,结果是10天、11天、12天、15天,甚至7月12日和15日都不是连续的。理想情况下,它不应该获取任何行。非常感谢您对解决问题的任何帮助。谢谢