如何将 DateDiff 用于只有一个 SELECT 语句?
How to use DateDiff into only one SELECT statement?
我想在 SQL 查询的 DATEDIFF 函数上制作一个简短的版本。在我的代码中,我在那里创建了两个临时表,我 select 并使用 DATEDIFF 函数。
我希望简化此代码,只使用一个 SELECT 语句来提供相同的结果。可能吗?
这是我的结果:
这是我的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
谢谢!
您可以删除对临时表的插入并在最终查询中使用子选择:
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
如果您使用的是 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
在 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;
试一试,
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
我想在 SQL 查询的 DATEDIFF 函数上制作一个简短的版本。在我的代码中,我在那里创建了两个临时表,我 select 并使用 DATEDIFF 函数。
我希望简化此代码,只使用一个 SELECT 语句来提供相同的结果。可能吗?
这是我的结果:
这是我的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
谢谢!
您可以删除对临时表的插入并在最终查询中使用子选择:
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
如果您使用的是 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
在 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;
试一试,
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