【问题标题】:How to use DateDiff into only one SELECT statement?如何仅在一个 SELECT 语句中使用 DateDiff?
【发布时间】:2016-12-26 16:13:21
【问题描述】:

我想对我的 SQL 查询中的 DATEDIFF 函数制作一个简短的版本。在我的代码中,我创建了两个临时表,然后在那里选择并使用 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

谢谢!

【问题讨论】:

  • 如果您在 2012 年以上,请使用 Lead()/Lag()

标签: sql sql-server select datediff


【解决方案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

【讨论】:

    【解决方案2】:

    试一试,

    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
    

    【讨论】:

      【解决方案3】:

      在 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;
      

      【讨论】:

        【解决方案4】:

        您可以删除插入临时表并在最终查询中使用子选择:

        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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-17
          • 1970-01-01
          • 1970-01-01
          • 2021-01-05
          • 1970-01-01
          • 2017-04-12
          相关资源
          最近更新 更多