Oracle取前一点或后一点数据

来源:互联网 发布:三维设计与渲染软件 编辑:程序博客网 时间:2024/06/05 14:10
eg:

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

0 0
原创粉丝点击