Jerley Garcia
Jerley Garcia

Reputation: 33

How to use DateDiff into only one SELECT statement?

I want to make a short version on my DATEDIFF function on my SQL Query. In my code, I created two temporary tables then there, I select and use the DATEDIFF funtion.

I would want this code to be simplified and only use ONE SELECT statement that will provide the same results. Is it possible?

Here is my result:
enter image description here

This is my SQL Query

DECLARE @Temp TABLE (ID int, Stamp datetime)

INSERT INTO @Temp (ID, Stamp) VALUES (1, '2016-08-17')
INSERT INTO @Temp (ID, Stamp) VALUES (1, GETDATE())
INSERT INTO @Temp (ID, Stamp) VALUES (1, GETDATE()+0.5)
INSERT INTO @Temp (ID, Stamp) VALUES (2, '2016-08-16')
INSERT INTO @Temp (ID, Stamp) VALUES (2, GETDATE())
INSERT INTO @Temp (ID, Stamp) VALUES (2, GETDATE()+3)

SELECT ROW_NUMBER() OVER (ORDER BY ID) as c, ID, Stamp INTO #Temp2 
FROM @Temp

SELECT ROW_NUMBER() OVER (ORDER BY ID) as d, ID, Stamp INTO #Temp3 
FROM @Temp

SELECT temp2.ID, temp2.Stamp, ISNULL(DATEDIFF(day, temp3.Stamp, temp2.Stamp),0) as DateDiff
FROM #Temp2 as temp2
LEFT JOIN #Temp3 as temp3 on temp2.ID = temp3.ID and temp2.c = temp3.d + 1

Thanks!

Upvotes: 2

Views: 701

Answers (4)

TheGameiswar
TheGameiswar

Reputation: 28900

If you are using SQL Server 2012:

select * ,isnull(datediff(day,lag(stamp) over(partition by id order by stamp),stamp) ,0) 
from @temp t1

Else use this..

;with cte
as
(select * ,row_number() over (partition by id order by stamp ) as rownum
from @temp t1
)
select c1.id,c1.stamp,isnull(datediff(day,c2.stamp,c1.stamp),0) as datee
 from cte c1
left join
cte c2
on c1.id=c2.id and c1.rownum=c2.rownum+1

Upvotes: 1

Jatin Patel
Jatin Patel

Reputation: 2104

try a cte,

DECLARE @Temp TABLE (ID int, Stamp datetime)

INSERT INTO @Temp (ID, Stamp) VALUES (1, '2016-08-17')
INSERT INTO @Temp (ID, Stamp) VALUES (1, GETDATE())
INSERT INTO @Temp (ID, Stamp) VALUES (1, GETDATE()+0.5)
INSERT INTO @Temp (ID, Stamp) VALUES (2, '2016-08-16')
INSERT INTO @Temp (ID, Stamp) VALUES (2, GETDATE())
INSERT INTO @Temp (ID, Stamp) VALUES (2, GETDATE()+3)

;WITH CTE AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY ID) as RowNo, ID, Stamp 
    FROM @Temp
)

SELECT temp2.ID, temp2.Stamp, ISNULL(DATEDIFF(day, temp3.Stamp, temp2.Stamp),0) as DateDiff
FROM CTE as temp2
LEFT JOIN CTE as temp3 on temp2.ID = temp3.ID 
    AND temp2.RowNo = temp3.RowNo + 1

Upvotes: 0

Gordon Linoff
Gordon Linoff

Reputation: 1269753

In SQL Server 2012+, you would just use lag():

select t.*
       isnull(datediff(day, lag(stamp) over (partition by id order by stamp), stamp), 0)
from @temp t;

In earlier versions, I would use outer apply:

select t.*,
       isnull(datediff(day, t2.stamp, t.stamp), 0)
from @temp t outer apply
     (select top 1 t2.*
      from @temp t2
      where t2.id = t.id and t2.stamp < t.stamp
      order by t2.stamp desc
     ) t2;

Upvotes: 0

Geert Immerzeel
Geert Immerzeel

Reputation: 564

You could remove insert into the temp-tables and use subselects within the final query:

DECLARE @Temp TABLE (ID int, Stamp datetime)

INSERT INTO @Temp (ID, Stamp) VALUES (1, '2016-08-17')
INSERT INTO @Temp (ID, Stamp) VALUES (1, GETDATE())
INSERT INTO @Temp (ID, Stamp) VALUES (1, GETDATE()+0.5)
INSERT INTO @Temp (ID, Stamp) VALUES (2, '2016-08-16')
INSERT INTO @Temp (ID, Stamp) VALUES (2, GETDATE())
INSERT INTO @Temp (ID, Stamp) VALUES (2, GETDATE()+3)

SELECT temp2.ID, temp2.Stamp, ISNULL(DATEDIFF(day, temp3.Stamp, temp2.Stamp),0) as DateDiff
FROM (SELECT ROW_NUMBER() OVER (ORDER BY ID) as c, ID, Stamp FROM @Temp) as temp2
LEFT JOIN (SELECT ROW_NUMBER() OVER (ORDER BY ID) as d, ID, Stamp FROM @Temp) as temp3 
on temp2.ID = temp3.ID and temp2.c = temp3.d + 1

Upvotes: 0

Related Questions