如何使用滑动日期但特定时间进行动态 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。
我正在尝试进行动态查询,以搜索从 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。