简体   繁体   中英

Mathematical comparison between rows

I have a table

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

I need to get the difference between the end time of one row and the start time of the NEXT row. ie End time of row 1 compared to start time of row 2, or end time of row 2 compared to start time of row 3.

Ideally I'd like a result that looks similar to

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

I have no clue whatsoever on how to do something like this. I'm thinking that I may need 2 temp tables, one to hold start times another for end times so that I can more easily do the comparisons, but honestly that's just a shot in the dark at the moment.

FYI, on server 2008 in case that makes a difference for some of the commands.

NOTE: The question was not tagged SQL Server 2008 when this answer was written.

You can use lag() :

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

This does not filter out any rows. The description of the problem ("next row") and the sample data (which is based on "previous row") are inconsistent.

Well, since it's 2008 version you can't use the Lead() or Lag() window functions, but you can use subqueries to mimic them:

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    
)

You can try it

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 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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