为表/列表中的每个条目选择上一行

时间:2015-07-22 19:04:55

标签: sql sql-server-2008-r2

Row       TimeStamp
____|________________________
1   | 2015-01-01 12:00:01.000
2   | 2015-01-01 12:00:02.000
3   | 2015-01-01 12:00:03.000
4   | 2015-01-01 12:00:04.000
5   | 2015-01-01 12:00:05.000
6   | 2015-01-01 12:00:06.000
7   | 2015-01-01 12:00:07.000
8   | 2015-01-01 12:00:08.000
9   | 2015-01-01 12:00:09.000

选择上一行的TimeStamp是一项相当简单的任务

e.g。

SELECT  MAX([TimeStamp])
FROM [MyTable] 
WHERE [TimeStamp] < '2015-01-01 12:00:02.000'

按预期获得2015-01-01 12:00:01.000

但是我在从多个前面的行中选择一个TimeStamps列表时遇到了一些麻烦。

例如,如果我想获得Row&gt; = 3&amp;&amp;的前面行的时间戳。 &lt; = 6

(i.e. 
    SELECT [TimeStamp]
    FROM [MyTable] 
    WHERE [Row] >= 3 AND [Row] <= 6

    =>

    TimeStamps     
    2015-01-01 12:00:03.000
    2015-01-01 12:00:04.000
    2015-01-01 12:00:05.000
    2015-01-01 12:00:06.000
)

我如何为这些结果行的每个获取前面的TimeStamp?

(i.e. 
    TimeStamps                   
    2015-01-01 12:00:02.000
    2015-01-01 12:00:03.000
    2015-01-01 12:00:04.000
    2015-01-01 12:00:05.000
)

我见过很多与lag / lead相关的解决方案,但我对SQLServer 2008的使用很难改变。

3 个答案:

答案 0 :(得分:1)

你可以试试这个:

SELECT 
    t.TimeStamp,
    (
     SELECT MAX(t1.TimeStamp)
        FROM MyTable t1
        WHERE t1.Row < t.Row
    ) AS PrevTimeStamp
FROM MyTable t
WHERE t.Row >= 3 AND t.Row <= 6

这将为您提供并排的列,一个是当前列,另一个是前一列。

答案 1 :(得分:0)

select b.id, max(a.timestamp)
from mytable a join mytable b 
on a.id < b.id
where b.id between --desired values
group by b.id

以下是样本数据的小提琴:fiddle

这对你有用吗?这将在所有先前的行上join,然后选择max时间戳,该时间戳始终是前一行的值,假设时间戳列按升序排序。

答案 2 :(得分:0)

您可以使用CTE对行进行编号,并使用left join查找上一行:

; with  numbered as
        (
        select  row_number() over (order by TimeStamp) as rn
        ,       *
        from    YourTable
        )
select  cur.TimeStamp
,       prev.TimeStamp
from    numbered cur
left join
        numbered prev
on      prev.rn + 1 = cur.rn
where   cur.row between 3 and 6