【问题标题】:Rounding SQL DateTime to midnight将 SQL DateTime 舍入到午夜
【发布时间】:2011-12-18 22:24:56
【问题描述】:

我的 SQL 查询有一个小问题。我正在使用 GETDATE 函数,但是,假设我在下午 5 点执行脚本,它将在 2011 年 12 月 12 日下午 5 点到 2011 年 12 月 18 日下午 5 点之间提取记录。我怎样才能让它拉起整个 12/12/2011 - 12/18/2011 基本上忽略时间的记录。

我的脚本:

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate > (GETDATE()-6)  

【问题讨论】:

    标签: sql sql-server sql-server-2005 getdate


    【解决方案1】:

    在 SQL Server 2008 和更高版本中,您可以将 DateTime 强制转换为 Date,这会删除时间元素。

    WHERE Orders.OrderStatus = 'Shipped'  
    AND Orders.ShipDate >= (cast(GETDATE()-6 as date))  
    

    在 SQL Server 2005 及以下您可以使用:

    WHERE Orders.OrderStatus = 'Shipped'  
    AND Orders.ShipDate >= DateAdd(Day, Datediff(Day,0, GetDate() -6), 0)
    

    【讨论】:

    • 我得到这个类型日期不是定义的系统类型。
    • 我猜你当时没有使用 SQL 2008 :)
    • @user1090389 这就是为什么我把字符串转换选项;D
    • @DaveShaw - 里面缺少一个 DATEADD
    • 抱歉@Dems Dave 看起来不那么复杂
    【解决方案2】:

    这是我发现的最简单的东西

    -- Midnight floor of current date
    
    SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()))
    

    DATEDIFF 返回 1900-1-1 之前或之后的整数天数, 并且 Convert Datetime 很乐意将它带回到午夜的那个日期。

    由于 DateDiff 返回一个整数,您可以使用加减天数来获得正确的偏移量。

    SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()) + @dayOffset)
    

    这不是四舍五入这是截断...但我认为这是被问到的。 (四舍五入加一并截断……这也不是四舍五入,即天花板,而是 再次很可能是您想要的。要真正四舍五入添加 .5(这行得通吗?)并截断。

    事实证明,您可以将 .5 添加到 GetDate() 并按预期工作。

    -- Round Current time to midnight today or midnight tomorrow
    
    SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE() + .5))
    

    我在 SQL Server 2008 上进行了所有试验,但我认为这些功能也适用于 2005。

    【讨论】:

    • 这适用于 2k5 刚刚测试过。 where [ScanDate] >= convert(datetime, datediff(day, 0, getdate())) and [ScanDate] < convert(datetime, datediff(day, -1, getdate()))
    【解决方案3】:
    --
    -- SQL DATEDIFF getting midnight time parts 
    --
    SELECT GETDATE() AS Now, 
       Convert(DateTime, DATEDIFF(DAY, 0, GETDATE())) AS MidnightToday,
       Convert(DateTime, DATEDIFF(DAY, -1, GETDATE())) AS MidnightNextDay,
       Convert(DateTime, DATEDIFF(DAY, 1, GETDATE())) AS MidnightYesterDay
    go
    Now                   MidnightToday          MidnightNextDay        MidnightYesterDay     
     --------------------  ---------------------  ---------------------  --------------------- 
     8/27/2014 4:30:22 PM  8/27/2014 12:00:00 AM  8/28/2014 12:00:00 AM  8/26/2014 12:00:00 AM 
    

    【讨论】:

      【解决方案4】:
      SELECT getdate()
      

      结果:2012-12-14 16:03:33.360

      SELECT convert(datetime,convert(bigint, getdate()))
      

      结果 2012-12-15 00:00:00.000

      【讨论】:

      • 感谢您的反馈。我想强调的是,转换为 bigint 并返回会为您进行四舍五入。
      • 如果时间在中午之后,此代码会将其四舍五入到一天结束时的午夜,这会导致半天错误。
      • 使用此方法可能会在以后使用较大的数据集时导致性能影响。
      【解决方案5】:

      您可以将日期时间转换为日期,然后再转换回日期时间。这将重置时间戳。

      选择 getdate() --2020-05-05 13:53:35.863 选择演员(演员(GETDATE()作为日期)作为日期时间)--2020-05-05 00:00:00.000

      【讨论】:

        【解决方案6】:

        正如@BassamMehanni 所述,您可以在 SQL Server 2008 及更高版本中转换为 DATE...

        SELECT
          *
        FROM
          yourTable
        WHERE
              dateField >= CAST(GetDate() - 6 AS DATE)
          AND dateField <  CAST(GetDate() + 1 AS DATE)
        

        第二个条件实际上可以只是GetDate(),但我将这种格式显示为Less Than DateX 的示例,以避免将 dateField 也转换为 DATE,从而大大提高性能。


        如果你是 2005 年或以下,你可以使用这个...

        SELECT
          *
        FROM
          yourTable
        WHERE
              dateField >= DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) - 6, 0)
          AND dateField <  DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) + 1, 0)
        

        【讨论】:

          【解决方案7】:

          试试这个。

          WHERE Orders.OrderStatus = 'Shipped'  
          AND Orders.ShipDate >= CONVERT(DATE, GETDATE())
          

          【讨论】:

            【解决方案8】:

            这可能看起来很便宜,但它对我有用

            SELECT CONVERT(DATETIME,LEFT(CONVERT(VARCHAR,@dateFieldOrVariable,101),10)+'00:00:00.000')

            【讨论】:

              【解决方案9】:

              我经常这样做

              SELECT *
              FROM MyTable
              WHERE CONVERT(VARCHAR, MyTable.dateField, 101) = CONVERT(VARCHAR, GETDATE(), 101)
              

              如果你使用的是 SQL SERVER 2008,你可以这样做

              SELECT *
              FROM MyTable
              WHERE CAST(MyTable.dateField AS DATE) = CAST(GETDATE() AS DATE)
              

              希望对你有帮助

              【讨论】:

              • 如果你使用第一个例子,你destory优化器使用索引等的能力。使用字符串函数进行日期算术和比较是一个非常糟糕的主意。 (imo)甚至不应该被提及,这是一个糟糕的选择。
              • 如果您使用的是 SQL Server 2008,则不必这样做,否则,我不确定您如何在 SQL Server 2000/2005 中执行此操作,不胜感激,谢谢。
              • 公平地说。这两个选项都会破坏优化器使用索引的能力。您应该在过滤谓词列上执行和功能。这包括演员表。
              【解决方案10】:

              你可以把时间四舍五入。

              使用下面的ROUND 会将其舍入到午夜。

              WHERE Orders.OrderStatus = 'Shipped'  
              AND Orders.ShipDate >  CONVERT(datetime, (ROUND(convert(float, getdate()-6.5),0)))
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-01-13
                • 2021-09-23
                • 1970-01-01
                相关资源
                最近更新 更多