行之间的数学比较

时间:2017-08-03 13:45:40

标签: sql sql-server sql-server-2008

我有一张桌子

+----+-----------+---------+
| ID | StartTime | EndTime |
+----+-----------+---------+
|  1 | 2:00pm    | 3:00pm  |
|  2 | 4:00pm    | 5:00pm  |
|  3 | 7:00pm    | 9:00pm  |
+----+-----------+---------+

我需要得到一行的结束时间和NEXT行的开始时间之间的差异。即第1行的结束时间与第2行的开始时间相比,或第2行的结束时间与第3行的开始时间相比。

理想情况下,我希望结果与

类似
+----+----------------+
| ID | TimeDifference |
+----+----------------+
|  2 | 1.0 hours      |
|  3 | 2.0 hours      |
+----+----------------+

我对如何做这样的事情一无所知。我认为我可能需要2个临时表,一个可以在结束时间保持另一个临时表,这样我就可以更容易地进行比较,但说实话,这只是目前在黑暗中的一个镜头。

仅供参考,在服务器2008上,如果某些命令有所不同。

3 个答案:

答案 0 :(得分:4)

注意:撰写此答案时,问题未标记为SQL Server 2008。

您可以使用lag()

select t.*,
       datediff(minute, lag(endtime) over (order by id), starttime) / 60.0 as hours_diff
from t;

这不会过滤掉任何行。问题描述(“下一行”)和样本数据(基于“前一行”)不一致。

答案 1 :(得分:2)

嗯,因为它是2008版本,你不能使用Lead()Lag()窗口函数,但你可以使用子查询来模仿它们:

SELECT Id, 
       DATEDIFF(minute,
            (
                SELECT TOP 1 EndTime
                FROM table t1
                WHERE t1.Id < t0.Id 
                ORDER BY t1.Id DESC
            ), StartTime) / 60.0 As TimeDifference 
FROM Table t0
WHERE EXISTS             
(
    SELECT 1 
    FROM Table t2
    WHERE t2.Id < t0.Id    
)

答案 2 :(得分:1)

你可以尝试一下

declare @t as table (ID int,  StartTime time , EndTime time)
INSERT @t SELECT 1  ,'2:00pm',     '3:00pm'  
INSERT @t SELECT 2  ,'4:00pm',     '5:00pm'  
INSERT @t SELECT 3  ,'7:00pm',     '9:00pm'


---- For sequential IDs
select 
a.ID
,a.StartTime
,a.EndTime
,datediff(minute, (SELECT EndTime FROM @t b where b.ID = a.ID - 1) , a.StartTime) / 60.0 as hours_diff
from @t a 


---- For non-sequential IDs

;WIth cte_times as (
SELECT 
    ROW_NUMBER() OVER (ORDER BY Id) as new_ID
    , ID
    ,StartTime
    ,EndTime
FROM 
    @t
) 
select 
a.ID
,a.StartTime
,a.EndTime
,datediff(minute, (SELECT EndTime FROM cte_times b where b.new_ID = a.new_ID - 1) , a.StartTime) / 60.0 as hours_diff
from cte_times a