create table t_tmp as
select 1 p,5 x,4 v from dual
union
select 2,4,6 from dual
union
select 3,6,8 from dual
union
select 4,9,5 from dual
union
select 5,3,7 from dual;
select * from t_tmp order by p;
P X Y
1 5 4
2 4 6
3 6 8
4 9 5
5 3 7
其中字段p是连续有顺序的,字段x,y 任意数值;
求:连续3条记录的数据:
例如:
当前点 前一点 后一点
1,5,4 5,3,7,2,4,6
2,4,6,1,5,4,3,6,8
3,6,8,2,4,6,4,9,5
4,9,5,3,6,8,5,3,7
5,3,7,4,9,5,1,5,4
即1-5循环,取得第一点和最后一点的前后数据?
测试如下sql:
SELECT t1.*,t3.*,t2.*
FROM t_tmp t1, t_tmp t2, t_tmp t3
where t1.p = t2.p - 1
and t1.p = t3.p + 1
ORDER BY t1.p;
p=1和5时,数据不合适,修改sql如下:
with tmax as
(select t.*,
row_number() over(order by p desc) rn1,
row_number() over(order by p) rn2
from t_tmp t)
SELECT t1.p,
t1.x,
t1.v,
nvl(t3.p, t4.p) p,
nvl(t3.x, t4.x) x,
nvl(t3.v, t4.v) v,
nvl(t2.p, t5.p) p,
nvl(t2.x, t5.x) x,
nvl(t2.v, t5.v) v
FROM t_tmp t1
left join t_tmp t2
on t1.p = t2.p - 1
left join t_tmp t3
on t1.p = t3.p + 1
join tmax t4
on t4.rn1 = 1
join tmax t5
on t5.rn2 = 1
ORDER BY t1.p;
上面没有用分析函数,lag(LAG可以访问组中当前行之前的行),lead(LEAD可以访问组中当前行之后的行),用分析函数解决以上问题,sql如下:
with tmax as
(select t.*,
row_number() over(order by p desc) rn1,
row_number() over(order by p) rn2
from t_tmp t)
select t.p,t.x,t.v,
NVL(lag(t.p) over(order by t.p),t3.p) as p1,NVL(lag(t.x) over(order by t.p),t3.x) as x1,NVL(lag(t.v) over(order by t.p),t3.v) as v1,
NVL(lead(t.p) over(order by t.p),t4.p) as p2,NVL(lead(t.x) over(order by t.p),t4.x) as x2,NVL(lead(t.v) over(order by t.p),t4.v) as v2
from t_tmp t,tmax t3,tmax t4
where t3.rn1=1
and t4.rn2=1
order by t.p