如何使用滑动日期但特定时间进行动态 SQL 服务器查询?

How can I make a dynamic SQL Server query with sliding dates but specific times?

我正在尝试进行动态查询,以搜索从 9 天前 21:00 到 2 天前 23:00 的记录。

我被要求在 Maximo 中制作一份每周报告,其中列出星期日 21:00 和随后的星期五 23:00 之间的所有记录。该报告必须每周二在 6:00 生成。我从其他查询中拼凑了一些东西,但无法弄清楚从这里去哪里:

startdatetime >= dateadd(hour, 21, dateadd(dd, datediff(dd, 0, getdate()), 0))
and startdatetime <= dateadd(hour, 23, dateadd(dd, datediff(dd, 0, getdate()), 0))

我以前使用 DATEADD 来显示当天特定时间之间的所有记录。我想不通的是如何获得以前日期的那些时间。我尝试做“...dateadd(dd,datediff(dd,0,getdate()-9),0) 和...dateadd(dd,datediff(dd,0,getdate()-2),0)” ,但我得到了 SQL 错误代码 207。我显然不明白第二个 DATEADD 段是如何工作的。谁能告诉我我做错了什么?

你真的很接近,你只需要将第二个零更改为你想要移动的天数。

WHERE startdatetime >= dateadd(hour,21,dateadd(dd,datediff(dd,0,getdate()),-9))
AND startdatetime <= dateadd(hour,23,dateadd(dd,datediff(dd,0,getdate()),-3))

错误 207 引用了无效的列名。请确保您的查询中没有任何拼写错误,并且这些列确实存在。

使用 0 作为基础(等同于 1900-01-01)不是很直观或自我记录。另外编写一个假设它只会在星期二 运行 的查询有点危险;我们可以做到,如果它需要在周三或周四再次 运行,它仍然会产生正确的结果。

-- first, let's make sure we know what weekday is a Sunday
DECLARE @OriginalDateFirst int = @@DATEFIRST;

IF @OriginalDateFirst <> 7
BEGIN
  SET DATEFIRST 7;
END

-- let's figure out today
DECLARE @today datetime = CONVERT(date, GETDATE()),
        @weekday int = DATEPART(WEEKDAY, GETDATE());

-- if weekday is 3 (Tuesday), the previous Sunday is today -2, 
-- and the Sunday before that is today -9

-- if weekday is 4 (Wednesday), the days are -3, -10
-- if weekday is 5 (Thursday),  the days are -4, -11
-- and so on

-- so the range is -6-@weekday to 1-@weekday
DECLARE @MostRecentSunday datetime = DATEADD(HOUR, 23, DATEADD(DAY,  1-@weekday, @today)),
        @PreviousSunday   datetime = DATEADD(HOUR, 21, DATEADD(DAY, -6-@weekday, @today));

-- make sure this is what you want:
SELECT @PreviousSunday, @MostRecentSunday;

-- now your query just says:
... WHERE startdatetime >= @PreviousSunday
      AND startdatetime <= @MostRecentSunday;

-- let's put the datefirst setting back
IF @OriginalDateFirst <> 7
BEGIN
  SET DATEFIRST @OriginalDateFirst;
END

是的,它肯定有更多的代码(尽管如果你愿意,你可以将它压缩很多,而且如果你知道没有人会弄乱 DATEFIRST,你也可以清除其中的一些逻辑)。

但我更喜欢让代码自文档化而不是 terse/cryptic。