SQL Server:从第1行中提取第2行,从第2行提取第3行等

时间:2015-01-16 11:36:51

标签: sql-server tsql

我正在努力学习SQL服务器中的算法,我不知道如何解决这个问题。 我有一个带有时间戳的列,我已经通过desc订购了这个列。

我需要找出第二行与第一行,第三行和第二行之间的差异,并将其显示在一个新行中。最终表应如下所示:

ID                        Type                 Time_Stamp      Difference

xxx                       YYY                  00:03:12          00:00:02
xxx                       ZZZ                  00:03:14          00:00:02
xxx                       ZZZ                  00:03:16

我可以使用某种SQL函数吗?如果您有任何想法,请告诉我。

干杯,

2 个答案:

答案 0 :(得分:1)

样本表

CREATE TABLE #TEMP(ID VARCHAR(10),[TYPE] VARCHAR(10),TIME_STAMP TIME)

INSERT INTO #TEMP

SELECT 'xxx' ,                      'YYY',                  '00:03:12'   
UNION ALL      
SELECT 'xxx',                       'ZZZ',                  '00:03:14' 
UNION ALL       
SELECT 'xxx',                       'ZZZ',                  '00:03:16'

您需要使用自连接逻辑来获取下一行的记录

<强> QUERY

;WITH CTE AS
(
    SELECT ROW_NUMBER()OVER(ORDER BY TIME_STAMP)RNO,*
    FROM #TEMP
)
SELECT C1.*,'00:00:'+CAST(DATEDIFF(S,C1.TIME_STAMP,C2.TIME_STAMP)AS VARCHAR(2)) D
FROM CTE C1 
LEFT JOIN CTE C2 ON C1.RNO=C2.RNO-1

答案 1 :(得分:1)

使用Window Function

;WITH cte
     AS (SELECT Row_number()
                  OVER(
                    ORDER BY time_stamp) rn,
                *
         FROM   yourtable)
SELECT a.ID,
       a.Type,
       a.Time_Stamp,
       CONVERT(VARCHAR(10), Datediff(second, a.Time_Stamp, b.Time_Stamp)/3600)
       + ':'
       + RIGHT('00'+CONVERT(VARCHAR(2), (Datediff(second, a.Time_Stamp, b.Time_Stamp)%3600)/60), 2)
       + ':'
       + RIGHT('00'+CONVERT(VARCHAR(2), Datediff(second, a.Time_Stamp, b.Time_Stamp)%60), 2) AS [Difference]
FROM   cte a
       LEFT JOIN cte b
              ON a.rn = b.rn - 1 

如果您使用的是Sql Server 2012+,请使用Lead功能

;WITH cte
     AS (SELECT *,
                Datediff(second, time_stamp, Lead(time_stamp)
                                               OVER(
                                                 ORDER BY time_stamp)) AS Sec
         FROM   yourtable)
SELECT a.ID,
       a.Type,
       a.Time_Stamp,
       CONVERT(VARCHAR(10), sec/3600) + ':'
       + RIGHT('00'+CONVERT(VARCHAR(2), (sec%3600)/60), 2)
       + ':'
       + RIGHT('00'+CONVERT(VARCHAR(2), sec%60), 2) AS [Difference]
FROM   cte a 

更新:要插入temp table,请执行此操作。

;WITH cte
     AS (SELECT Row_number()
                  OVER(
                    ORDER BY time_stamp) rn,
                *
         FROM   yourtable)
SELECT a.ID,
       a.Type,
       a.Time_Stamp,
       CONVERT(VARCHAR(10), Datediff(second, a.Time_Stamp, b.Time_Stamp)/3600)
       + ':'
       + RIGHT('00'+CONVERT(VARCHAR(2), (Datediff(second, a.Time_Stamp, b.Time_Stamp)%3600)/60), 2)
       + ':'
       + RIGHT('00'+CONVERT(VARCHAR(2), Datediff(second, a.Time_Stamp, b.Time_Stamp)%60), 2) AS [Difference] 
into #tempTable    --Here you need to use into temptable
FROM   cte a
       LEFT JOIN cte b
              ON a.rn = b.rn - 1 

create临时表并使用

......
 Insert into #temptable
 SELECT a.ID,
           a.Type,
           a.Time_Stamp
......