SQL Server 如何跨多天查询每天指定小时范围内的数据?
可以。SQL Server 的 DATEPART(hour, TrxnDate) 返回小时整数,可以直接用于 BETWEEN。要查询每天从 00:00 开始、到 06:00 之前的记录,可以使用 BETWEEN 0 AND 5,也可以写成 DATEPART(hour, TrxnDate) < 6。
查询每天 00 至 06 之前的记录
SELECT TrxnDate, UserName, UserType
FROM MyTable
WHERE DATEPART(hour, TrxnDate) BETWEEN 0 AND 5;
BETWEEN 包含两端,这里匹配小时值 0、1、2、3、4、5。查询会返回所有日期中这些小时内的记录,不必逐日列出日期时间范围。
也可以用更简洁的等价写法:
SELECT TrxnDate, UserName, UserType
FROM MyTable
WHERE DATEPART(hour, TrxnDate) < 6;
为什么原来的条件会多查一个小时?
下面的条件可以执行,但会包含整个 06 点时段:
WHERE DATEPART(hour, TrxnDate) <= 6
例如,06:30:00 的小时部分也是 6,因此会被选中。如果要求在 06:00 之前结束,应使用 < 6 或 BETWEEN 0 AND 5。
这类条件适合按整点划分范围。如果要筛选 00:30 到 05:45,只提取小时就不够了,需要比较时间部分。
同时限定查询日期
如果只查询 2026 年 1 月 1 日至 1 月 2 日每天 00:00 至 06:00 之前的记录,可以组合日期范围和小时条件:
SELECT TrxnDate, UserName, UserType
FROM MyTable
WHERE TrxnDate >= '20260101'
AND TrxnDate < '20260103'
AND DATEPART(hour, TrxnDate) < 6;
日期条件采用左闭右开区间,包含 1 月 1 日和 1 月 2 日,排除 1 月 3 日。YYYYMMDD 日期字面量也能避免原示例中斜杠日期格式的解析歧义。
原 SQL 还有哪些地方需要调整?
原示例的 OR 前多了一个逗号。连接两个条件时,应写成:
WHERE (条件1 OR 条件2)
另外,不建议用 05:59:59.999 表示某个小时的最后时刻。SQL Server 的 datetime 精度有限,这个值可能被舍入到 06:00:00。比较完整日期时间时,使用 < 结束时间 更容易准确控制边界。
数据量较大时还要留意执行计划:对 TrxnDate 使用 DATEPART,通常无法直接利用普通日期索引按小时范围查找。如果查询有日期限制,保留对 TrxnDate 的直接范围比较,有助于先缩小需要处理的数据范围;具体效果取决于索引和数据分布。
备注:内容仅供参考。
