oracle数据库 求一条sql

有以下需求: 数据库为oracle
有一张表 tel(varchar2),up_time(timestamp)

数据: 1,2014-3-31 12:20:30
1,2014-3-31 12:20:35
1,2014-3-31 12:20:36
1,2014-3-31 12:21:01
1,2014-3-31 12:21:03
1,2014-3-31 12:21:05
1,2014-3-31 12:21:11
1,2014-3-31 12:21:15
1,2014-3-31 12:21:18

想得到以下数据:
1,2014-3-31 12:20:30
1,2014-3-31 12:20:35
1,2014-3-31 12:21:01
1,2014-3-31 12:21:11
1,2014-3-31 12:21:18
(大体意思就是以查询出来的第一条数据为基准 找到下一条间隔时间大于等于5秒的数据,然后以下一条数据为基准,再找到它的下一条大于等于5秒的数据,以此类推)
求大神解~~~~~~~

jynine
jynine 有没有数据库大牛啊? 等了这么久都不见回答呀
大约 6 年之前 回复
jynine
jynine 这个不能写存储过程~~~~~
大约 6 年之前 回复
lorewolf311
tianchao_ 写 存储过程?
大约 6 年之前 回复
jynine
jynine 没有人回答呀???????????
大约 6 年之前 回复

3个回答

[code="sql"]
select x.*,sys_connect_by_path(to_char(x.up_time,'yyyy-MM-dd hh:mi:ss'), '/' ) from (
select a.*,(select min(up_time) from t_test b where b.up_time >= a.add_time) next_time
from(
select t.*,t.up_time + 1/(24*60*60)*5 add_time from t_test t
) a
) x
start with x.up_time = to_date('2014-03-31 12:20:30','yyyy-MM-dd hh:mi:ss')
connect by prior x.next_time = x.up_time
[/code]

主要思路是通过oracle的connect by 递归实现,但实现的时候有个问题,就是你的表缺少字段来连接上下记录,所以要自己模拟

上面sql主要分成以下几个步骤:
1.[code="sql"]select t.*,t.up_time + 1/(24*60*60)*5 add_time from t_test t[/code]
增加一列表示up_time加上5秒是哪个时间,结果如果下:
[quote]
1 2014-03-31 12:20:30 2014-03-31 12:20:35
1 2014-03-31 12:20:35 2014-03-31 12:20:40
1 2014-03-31 12:20:36 2014-03-31 12:20:41
1 2014-03-31 12:21:01 2014-03-31 12:21:06
1 2014-03-31 12:21:03 2014-03-31 12:21:08
1 2014-03-31 12:21:05 2014-03-31 12:21:10
1 2014-03-31 12:21:11 2014-03-31 12:21:16
1 2014-03-31 12:21:15 2014-03-31 12:21:20
1 2014-03-31 12:21:18 2014-03-31 12:21:23

[/quote]
2.[code="sql"]select a.*,(select min(up_time) from t_test b where b.up_time >= a.add_time) next_time
from(
select t.*,t.up_time + 1/(24*60*60)*5 add_time from t_test t
) a[/code]
在步骤一的基础上,增加一列next_time,即根据步骤一计算出的列add_time(也就是up_time加上5秒的值)来得到此add_time与原表数据中的up_time哪个最近。结果如下:
[quote]
1 2014-03-31 12:20:30 2014-03-31 12:20:35 2014-03-31 12:20:35
1 2014-03-31 12:20:35 2014-03-31 12:20:40 2014-03-31 12:21:01
1 2014-03-31 12:20:36 2014-03-31 12:20:41 2014-03-31 12:21:01
1 2014-03-31 12:21:01 2014-03-31 12:21:06 2014-03-31 12:21:11
1 2014-03-31 12:21:03 2014-03-31 12:21:08 2014-03-31 12:21:11
1 2014-03-31 12:21:05 2014-03-31 12:21:10 2014-03-31 12:21:11
1 2014-03-31 12:21:11 2014-03-31 12:21:16 2014-03-31 12:21:18
1 2014-03-31 12:21:15 2014-03-31 12:21:20
1 2014-03-31 12:21:18 2014-03-31 12:21:23

[/quote]
3.这就可以根据步骤二得到的表结构进行oracle递归查询了,查询条件就是根据next_time=up_time来进行

iteye_7115
iteye_7115 用这么多分析函数啊?
大约 6 年之前 回复
jynine
jynine select up_time from (select up_time, count(0) over(order by cast(up_time as date) range between current row and 5/24/60/60 following) cnt, decode(row_number() over(order by up_time),1,0,row_number() over(order by up_time)) rn from t_test) start with rn = 0 connect by rn = prior cnt + prior rn ;
大约 6 年之前 回复
jynine
jynine 不错。 还可以参考一下这个sql: with tmp01 as (select 1 tel, to_date('2014-3-31 12:20:30', 'yyyy-mm-dd hh24:mi:ss') uptime from dual union all select 1 tel, to_date('2014-3-31 12:20:35', 'yyyy-mm-dd hh24:mi:ss') uptime from dual union all select 1 tel, to_date('2014-3-31 12:20:36', 'yyyy-mm-dd hh24:mi:ss') uptime from dual union all select 1 tel1, to_date('2014-3-31 12:21:01', 'yyyy-mm-dd hh24:mi:ss') uptime from dual union all select 1 tel, to_date('2014-3-31 12:21:03', 'yyyy-mm-dd hh24:mi:ss') uptime from dual union all select 1 tel, to_date('2014-3-31 12:21:05', 'yyyy-mm-dd hh24:mi:ss') uptime from dual union all select 1 tel, to_date('2014-3-31 12:21:11', 'yyyy-mm-dd hh24:mi:ss') uptime from dual union all select 1 tel, to_date('2014-3-31 12:21:15', 'yyyy-mm-dd hh24:mi:ss') uptime from dual union all select 1 tel, to_date('2014-3-31 12:21:18', 'yyyy-mm-dd hh24:mi:ss') uptime from dual), tmp02 as(select row_number() over(order by uptime asc) rn,t.* from tmp01 t), tmp03(RN,TEL,UPTIME,LEV) as ( select RN,TEL,UPTIME,1 LEV from TMP02 WHERE TEL=1 UNION ALL SELECT T2.RN,T2.TEL,T2.UPTIME,T1.LEV+1 FROM TMP03 T1,TMP02 T2 WHERE T2.RN>T1.RN AND (cast(T2.uptime as date)-cast(T1.uptime as date))*24*3600>=5 ) SELECT MIN(UPTIME) FROM TMP03 GROUP BY LEV ORDER BY LEV
大约 6 年之前 回复

没有想到好的方法,
但是为什么非要用sql呢,可以用程序处理,如果数据量不大的话,可以一次读出,在程序中操作,速度也很快。

为什么不在TABLE Design的时候考虑扩展一个Column出来保存与上一条Record的时间差呢?

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐