2016-08-19 22 views
2

我想在我的SQL查询上对DATEDIFF函数做一个简短的版本。在我的代码中,我创建了两个临时表,然后选择并使用DATEDIFF函数。如何将DateDiff仅用于一个SELECT语句?

我想这个代码被简化,只使用一个SELECT语句,将提供相同的结果。可能吗?

这里是我的结果:
enter image description here

这是我的SQL查询

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 

谢谢!

+0

如果您在使用2012+铅()/滞后() – Serg

回答

1

如果您正在使用SQL Server 2012:

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

否则使用这个..

;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 
+1

谢谢先生!这工作并简化了我的查询。 –

0

你可以删除插入到临时表和最终的查询中使用子查询:

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 
0

在SQL Server 2012+中,您只需使用lag()

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

在早期版本中,我会用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; 
0

尝试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 
相关问题