【问题标题】:SQL Server: convert to today then add 8 hours: part IISQL Server:转换到今天然后加上 8 小时:第二部分
【发布时间】:2012-10-02 03:51:22
【问题描述】:

在我较早的帖子中,我尝试将日期更改为当前日期并添加 8 小时时间。

SQL Server: convert to today then add 8 hours

UPDATE business.dbo.db_schedule
SET nextUpdate= DATEADD(hh, 8,
                DATEADD(d, DATEDIFF(D,nextUpdate,Getdate()),
                          nextUpdate))
where sno=8

注意:nextUpdate 可能是过去的任何时间。

如果我想更进一步;我希望 nextdate 在未来的时间。 因为如果我添加一次 8 小时,结果可能仍然是过去的时间,我可能必须再添加一个(甚至两次),所以结果是将来的。我可以一步完成吗?

【问题讨论】:

    标签: sql-server dateadd


    【解决方案1】:
    UPDATE business.dbo.db_schedule
    SET nextUpdate =
      DATEADD(HOUR
        , 8 * CEILING((DATEDIFF(MILLISECOND, nextUpdate, GETDATE()) / 3600000.) / 8.)
        , nextUpdate)
      )
    WHERE sno = 8;
    

    我们将 8 乘以 CELING,而不是仅仅添加 8 小时,nextUpdate 的小时数来自 GETDATE()

    例如如果 nextUpdate2012-10-01 02:30:00 并且 GETDATE() 当前是 2012-10-02 15:15:00,则有 36.75(四舍五入为 37)小时的差异。 37 / 8 的 CEILING 是 5,这意味着您需要添加 5 * 8 小时才能获得在 GETDATE() 之后的时间,但仍保留当前 nextUpdate 值的 8 小时的倍数。

    SQLFiddle example of the solution

    【讨论】:

    • 不错的逻辑。不过不太对。 "2012 年 9 月 26 日 22:00", curtime=06:04:21
    • @Richardakacyberkiwi 感谢您了解边缘情况。我将查询更新为毫秒而不是小时,这使得您提供的值可以按需要工作。
    【解决方案2】:

    我认为这虽然有很多值得一看的地方,但实际上会表现得更好,因为它只是一次遍历数据中的一堆计算。

    UPDATE business.dbo.db_schedule
    SET nextUpdate=
      CASE
      WHEN
                    DATEADD(hh, 8, DATEADD(d, DATEDIFF(
                    D,nextUpdate,Getdate()), nextUpdate))
                  > Getdate() THEN
                    DATEADD(hh, 8, DATEADD(d, DATEDIFF(
                    D,nextUpdate,Getdate()), nextUpdate))
      WHEN
                    DATEADD(hh, 16, DATEADD(d, DATEDIFF(
                    D,nextUpdate,Getdate()), nextUpdate))
                  > Getdate() THEN
                    DATEADD(hh, 16, DATEADD(d, DATEDIFF(
                    D,nextUpdate,Getdate()), nextUpdate))
      ELSE
                    DATEADD(d, 1+DATEDIFF(
                    D,nextUpdate,Getdate()), nextUpdate)
      END
    where sno=8
    

    注意:最后一个是通过在内部表达式中添加 1 天而不是在外部表达式中添加 24 小时来简化的。


    以下原创想法

    这个想法在前一个的基础上进行了扩展,只是我们不是只添加 8 小时,而是将所有 8、16 24 添加为 3 个单独的行,并使用 GROUP BY/MIN 来获取当前时间之后的最早时间。

    update s
    set nextUpdate = a.newTime
    from business.dbo.db_schedule s
    join
    (
      select nextupdate, min(nextUpdate2) newTime
      from
      (
        SELECT nextupdate,
               nextUpdate2 = 
                  DATEADD(hh, 8*x.y,
                      DATEADD(d,DATEDIFF(D,
                          d.nextUpdate,Getdate()),d.nextUpdate))
        from business.dbo.db_schedule d
        cross join (select 1 union all
                    select 2 union all
                    select 3) x(y)
      ) z
      where newTime > getdate()
      group by nextupdate
    ) a on a.nextUpdate = b.nextUpdate;
    

    【讨论】:

      猜你喜欢
      • 2012-09-22
      • 1970-01-01
      • 1970-01-01
      • 2016-12-04
      • 1970-01-01
      • 2017-09-03
      • 2014-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多