找出相邻行之间的差异,而不使用“延迟”。关键词

时间:2015-10-05 18:07:19

标签: sql sql-server azure-sql-database datediff

我有一些数据如下

ImageButton

我想找到TimeStamp中相邻行之间的差异以及得分,以便输出如下所示

ID,TimeStamp,Score
975191,9/26/2015 23:24,38
975191,9/26/2015 23:24,38
975191,9/26/2015 23:24,38
975191,9/26/2015 23:29,37
975191,9/27/2015 0:21,21
975191,9/27/2015 0:21,16
975191,9/27/2015 0:25,16
975191,9/27/2015 0:25,21
975191,9/27/2015 0:51,35
975191,9/27/2015 0:51,71
975191,9/27/2015 19:01,16
975191,9/27/2015 19:01,21
975191,9/27/2015 19:11,35
975191,9/27/2015 19:11,71
975191,9/28/2015 22:12,38

这是我写的查询

ID,TimeStamp,Score,Aging,Delta
975191,9/26/2015 23:24,38,1014527,-38
975191,9/26/2015 23:24,38,0,0
975191,9/26/2015 23:24,38,0,0
975191,9/26/2015 23:29,37,0,1
975191,9/27/2015 0:21,21,1,16
975191,9/27/2015 0:21,16,0,5
975191,9/27/2015 0:25,16,0,0
975191,9/27/2015 0:25,21,0,-5
975191,9/27/2015 0:51,35,0,-14
975191,9/27/2015 0:51,71,0,-36
975191,9/27/2015 19:01,16,19,55
975191,9/27/2015 19:01,21,0,-5
975191,9/27/2015 19:11,35,0,-14
975191,9/27/2015 19:11,71,0,-36
975191,9/28/2015 22:12,38,27,33

到目前为止一切顺利, 但是我希望在不使用lag关键字的情况下获得相同的输出,因为在SQL Azure上使用lag关键字会给我

SELECT
ID,
TimeStamp,
Score,
datediff(hour,ISNULL(convert(datetime, lag(TimeStamp) over(partition by ID order by Timestamp)), 0),TimeStamp) as Aging,
ISNULL(convert(int, lag(Score) over(partition by ID order by Timestamp)), 0) - Score as Delta
FROM TableName
order by TimeStamp asc

3 个答案:

答案 0 :(得分:0)

基于Giorgos的建议:

;With x AS (
  SELECT
  ROW_NUMBER() over (PARTITION BY ID ORDER BY TimeStamp) as RN,
  ID,
  TimeStamp,
  Score
  FROM TableName
  )

SELECT
X.ID,
X.TimeStamp,
X.Score,
datediff(hour,ISNULL(convert(datetime, Y.TimeStamp), 0),X.TimeStamp) as Aging,
ISNULL(convert(int, Y.Score), 0) - X.Score as Delta

FROM X
LEFT JOIN X as Y on X.ID = Y.ID and X.RN = Y.RN + 1

ORDER BY X.RN

答案 1 :(得分:0)

SQL Azure仍然有ROW_NUMBER,这就是我在SQL Server 2012中添加LAG之前的做法:

;WITH cte AS (
        SELECT
            ID,
            TimeStamp,
            Score,
            rn = row_number() over (parition by ID order by Timestamp)
        FROM TableName
    )

SELECT      c1.Id,
            c1.TimeStamp,
            c1.Score,
            datediff(hour,ISNULL(convert(datetime, c2.TimeStamp), 0), c1.TimeStamp) as Aging,
            ISNULL(convert(int, c2.Score), 0) - c1.Score AS DeltaScore          
FROM        cte c1
LEFT JOIN   cte c2      ON c1.ID = c2.ID
                        AND c1.rn = c2.rn + 1
order by    c1.TimeStamp asc

答案 2 :(得分:0)

近似lag()的一种方法是使用outer apply。与使用row_number()的方法相比,这可以获得更好的性能:

select s.*, sprev.*
from scores s outer apply
     (select top 1 s2.*
      from scores s2
      where s2.id = s.id and
            s2.timestamp < s.timestamp
      order by timestamp desc
     ) sprev;

为了提高性能,您需要scores(id, timestamp)上的索引。

注意:您的前三个时间戳似乎都是相同的。此版本(类似于lag())可能会产生不稳定的结果。您应该在order by中添加唯一ID(如果有的话)。