简体   繁体   English

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

[英]Get Value from Previous row/next row SQL

i have a table with 3 fields. 我有3个字段的表。 ie

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

What i would like to achieve...if possible...with a single query (no matter how many subqueries) but plain SQL (without pivot, CTE etc) is to get the same : placeid's transferdate from each row, on the previous row or to the next row so that i can make some calculations with them. 我想通过一个查询(无论有多少个子查询)但使用普通SQL(没有数据透视,CTE等)来实现...如果可能的话,将获得相同的结果:上一行中每一行的placeid的transferdate行或到下一行,以便我可以使用它们进行一些计算。 i mean : 我的意思是 :

 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)

I have achieved it with cursors in stored procedure or function or even using a temp table and i know how to do it with built-in recursive functions (ie Oracle) but my problem is that i need to use it as a subquery in a report SQL statement so it has to be plain SQL code as one statement. 我已经使用存储过程或函数中的游标甚至使用了临时表来实现了它,我知道如何使用内置的递归函数(即Oracle)来实现它,但是我的问题是我需要在报表中将其用作子查询SQL语句,因此它必须是纯SQL代码作为一个语句。

Thank you for your answer 谢谢您的回答

The SQL standard function to look into previous rows is LAG and to look into later rows is LEAD. 查看前几行的SQL标准函数是LAG,查看后几行的是LEAD。 They are not available in every dbms though. 但是,并非在每个dbms中都提供它们。 Just look it up, whether they are available. 只需查找一下,看看是否可用。

If not: The next value is always the minimum value of all greater values, the previous value is the maximum of all smaller values. 如果不是:下一个值始终是所有较大值的最小值,上一个值是所有较小值的最大值。 This should help you build a query. 这应该可以帮助您建立查询。

EDIT: Here is a simple query without LEAD for you: 编辑:这是一个没有铅的简单查询为您:

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;

EDIT: Here is the LEAD Version. 编辑:这是铅版本。 Available in Oracle as of version 8.1.6 . 从8.1.6版开始在Oracle中可用。

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

You can do this with a self-join and aggregation: 您可以通过自连接和聚合来实现:

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;

That said, I would not recommend actually using this query. 也就是说,我不建议您实际使用此查询。 In virtually every database, there are better approaches. 几乎在每个数据库中,都有更好的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM