Muffin13
Muffin13

Reputation: 13

Substract date from previous row by group SQL query

Data

id      date        
2380    10/30/12 09:00:00 
2380    10/30/12 09:05:00   
2380    10/30/12 09:10:00   
2380    10/30/12 09:15:00    
2381    10/30/12 10:00:00   
2381    10/30/12 10:05:00  
2381    10/30/12 10:10:00   
2381    10/30/12 10:15:00   
2382    10/30/12 11:00:00
2382    10/30/12 11:05:00
2382    10/30/12 10:10:00
2382    10/30/12 10:15:00

and I want the following solution

id      date                 duration        
2380    10/30/12 09:00:00    00:00:00 
2380    10/30/12 09:05:00    00:05:00   
2380    10/30/12 09:10:00    00:10:00
2380    10/30/12 09:15:00    00:15:00
2381    10/30/12 10:00:00    00:00:00
2381    10/30/12 10:05:00    00:05:00
2381    10/30/12 10:10:00    00:10:00
2381    10/30/12 10:15:00    00:15:00
2382    10/30/12 11:00:00    00:00:00
2382    10/30/12 11:05:00    00:05:00
2382    10/30/12 10:10:00    00:10:00
2382    10/30/12 10:15:00    00:10:00

I have tried to understand the logic behind the following thread but it's difficult to understand.

Substract date from previous row by group (using R)

select id, date, date - (select min(date) from date group by id) as duration 
from date

Closest I have got is for one id.

Upvotes: 0

Views: 80

Answers (2)

Vikrant More
Vikrant More

Reputation: 5442

Try this below example hope this is what you are looking as output,

declare @t1 table
(
    id int,
    dtdate datetime
)

insert into @t1 values(2380,'10/30/12 09:00:00') 
insert into @t1 values(2380,'10/30/12 09:05:00')   
insert into @t1 values(2380,'10/30/12 09:10:00')   
insert into @t1 values(2380,'10/30/12 09:15:00')    
insert into @t1 values(2381,'10/30/12 10:00:00')   
insert into @t1 values(2381,'10/30/12 10:05:00')  
insert into @t1 values(2381,'10/30/12 10:10:00')   
insert into @t1 values(2381,'10/30/12 10:15:00')   
insert into @t1 values(2382,'10/30/12 11:00:00')
insert into @t1 values(2382,'10/30/12 11:05:00')
insert into @t1 values(2382,'10/30/12 10:10:00')
insert into @t1 values(2382,'10/30/12 10:15:00')

;WITH CTE AS (
SELECT
rownum = ROW_NUMBER() OVER (partition by id ORDER BY id,dtDate),
id,dtDate
FROM @t1 p
)
SELECT
a.id,
a.dtDate,
CASE WHEN prev.dtdate is NULL THEN '00:00:00' ELSE convert(nvarchar(8),a.dtdate- prev.dtdate,108) END as duration 
FROM CTE a
LEFT JOIN CTE prev ON a.id = prev.id AND prev.rownum = a.rownum - 1

Upvotes: 3

Isaac
Isaac

Reputation: 3363

The key to my approach is to find the minimum date value for each id which I refer to as the ReferenceDate. Then I join the main table to that and do the date math with the DATEDIFF() function and transform the results to hh:mi:ss with the CONVERT() function using style 108. Here is the dbfiddle.

IF OBJECT_ID('tempdb.dbo.#MyTable', 'U') IS NOT NULL
    DROP TABLE #MyTable;

CREATE TABLE #MyTable
(
    id INTEGER NOT NULL
  , date DATETIME NOT NULL
);
INSERT INTO #MyTable (id, date) VALUES (2380, '10/30/12 09:00:00');
INSERT INTO #MyTable (id, date) VALUES (2380, '10/30/12 09:05:00');
INSERT INTO #MyTable (id, date) VALUES (2380, '10/30/12 09:10:00');
INSERT INTO #MyTable (id, date) VALUES (2380, '10/30/12 09:15:00');
INSERT INTO #MyTable (id, date) VALUES (2381, '10/30/12 10:00:00');
INSERT INTO #MyTable (id, date) VALUES (2381, '10/30/12 10:05:00');
INSERT INTO #MyTable (id, date) VALUES (2381, '10/30/12 10:10:00');
INSERT INTO #MyTable (id, date) VALUES (2381, '10/30/12 10:15:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 11:00:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 11:05:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 10:10:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 10:15:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 12:15:00');
INSERT INTO #MyTable (id, date) VALUES (2382, '10/30/12 10:15:30');

SELECT     a.*
         , CONVERT(NVARCHAR(8), a.date - b.ReferenceDate, 108) AS duration
FROM       #MyTable AS a
INNER JOIN (
    SELECT id, MIN(date) AS ReferenceDate 
    FROM #MyTable GROUP BY id) AS b ON a.id = b.id;

Upvotes: 0

Related Questions