oracle中怎么判断数据连续且大于某个值?

图片说明

数据如图所示,将时间以15分钟一个点存储在数据库中,如题,比如怎么判断至少3个点值大于100且这3个点时间连续(如0D,0D15,0D30)?sql要怎么写

先写一个笨办法:

select a.*
  from (select new_time,
               数值列,
               judge lead(judge_value, 1, 0) over(order by new_time) judge2,--用新的时间列找到下一个时间点
               lead(judge_value, 2, 0) over(order by new_time) judge3--用新的时间列找到下二个时间点
          from (select to_char(sysdate, 'yyyy-mm-dd') || ' ' ||
                       replace(时间列, 'D', ':') || ':00' as new_time,--重新规范了一下时间列,如果这个表里面有不止一天的数据,就不要这么转换了
                       数值列,
                       sign(数值列 - 100) as judge --用SIGN函数检验是不是大于100
                  FROM 表名
                 order by to_char(sysdate, 'yyyy-mm-dd') || ' ' ||
                          replace(时间列, 'D', ':') || ':00'))--重新规范时间排序,外面的开窗函数要用的新的时间列
 where judge = 1--最后在最外层判断三个是不是都是大于100的,然后取出这样的列
   and judge2 = 1--由于开窗函数在本层无法作为where条件,所以放在最外层
   and judge3 = 1--最后取到的时间列,往后推三个时间点就是你要的连续的三个大于100的时间点

还有一个比较高级的办法是用keep(),但是我忘了怎么用了,我去百度一下,明天再回复你,哇嘎嘎。

-------------------------我是昨天与今天的分隔符-------------------------

今天看了一下之前写的过程,发现其实不用keep()函数就可以做到,还是先上代码:

select *
  from (select a_time,
               a_value,
               judge,
               count(1) over(partition by j, judge) cnt
          from (select a.a_time,
                       a.a_value,
                       sign(a.a_value - 100) as judge,
                       row_number() over(order by a_time) - row_number() over(partition by sign(a.a_value - 100) order by a_time) j
                  from keep_test a))
 where judge = 1
   and cnt >= 3

我按照你的格式创建了一个新的测试表,并且做了测试,是没问题的。
测试表表名:keep_test
时间列:a_time
值列:a_value

感觉不好写,用存储过程试试?
筛出来大于300的点,然后排序后,判定里面有没有三个数据是时间连续的

但是像0D,0D30,0D45这种是列名,可以根据值筛选列名来比较吗?

可以写个函数,传入ROWNUM 和 值(比如100); 判断ROWNUM+1>100,ROWNUM+2>100; 是返回个 1, 不是返回0 ;
或者传入0D15自己+个数值也行; 都一样
这样凡是1的都意味着他后面有俩也是大于100的;