从上一行/下一行SQL获取值

时间:2014-09-04 13:57:48

标签: sql database-agnostic

我有一张包含3个字段的表格。即。

id, transferdate, placeid
---------------------------
1  | 1-4-2014 | 14 
2  | 4-4-2014 | 14 
5  | 10-4-2014| 14 
6  | 1-5-2013 | 13 
9  | 10-6-2013| 12

我想要实现的......如果可能的话...使用单个查询(无论有多少个子查询),但是纯SQL(没有pivot,CTE等)是得到相同的: 来自每一行的胎盘转移, 在前一行或下一行 这样我就可以用它们做一些计算。 我的意思是:

 id, transferdate, placeid, nexttransferdate
    --------------------------------------------
    1  | 1-4-2014 | 14        | 4-4-2014        
    2  | 4-4-2014 | 14        | 10-4-2014 
    5  | 10-4-2014| 14        | null (or transferdate)
    6  | 1-5-2013 | 13        | null (or transferdate)
    9  | 10-6-2013| 12        | null (or transferdate)

我已经用存储过程或函数中的游标实现了它,甚至使用了临时表,我知道如何使用内置的递归函数(即Oracle)来实现它,但我的问题是我需要将它用作子查询在报表SQL语句中,因此必须将纯SQL代码作为一个语句。

感谢您的回答

2 个答案:

答案 0 :(得分:2)

用于查看先前行的SQL标准函数是LAG,并且查看后面的行是LEAD。但它们并非在每个dbms中都可用。只要查看它们是否可用。

如果不是:下一个值始终是所有较大值的最小值,前一个值是所有较小值的最大值。这应该可以帮助您构建查询。

编辑:这是一个没有LEAD的简单查询:

select 
  id,
  transferdate,
  placeid,
  (
    select min(transferdate)
    from transfers latertransfers
    where latertransfers.placeid = transfers.placeid
    and latertransfers.transferdate > transfers.transferdate
  ) as nexttransferdate
from transfers
order by id;

编辑:这是LEAD版本。适用于Oracle 8.1.6版本。

select 
  id,
  transferdate,
  placeid,
  lead(transferdate) over (partition by placeid order by transferdate) as nexttransferdate
from transfers
order by id;

答案 1 :(得分:1)

您可以使用自联接和聚合执行此操作:

select t.id, t.transferdate, t.placeid, min(t.transferdate)
from table t left join
     table tnext
     on tnext.placeid = t.placeid and tnext.transferdate > t.transferdate
group by t.id, t.transferdate, t.placeid;

那就是说,我不建议实际使用这个查询。几乎在每个数据库中都有更好的方法。