1

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

SQL Server:转换为今天,然后增加 8 小时

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

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

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

4

2 回答 2

3
UPDATE business.dbo.db_schedule
SET nextUpdate =
  DATEADD(HOUR
    , 8 * CEILING((DATEDIFF(MILLISECOND, nextUpdate, GETDATE()) / 3600000.) / 8.)
    , nextUpdate)
  )
WHERE sno = 8;

我们不只是加 8 小时,而是将 8 乘以CELING相隔的小时nextUpdateGETDATE()

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

SQLFiddle 解决方案示例

于 2012-10-02T04:32:15.860 回答
1

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

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、1624 都添加为 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-10-02T06:21:02.660 回答