如何编写SQL从指定Datetime提取往前2小时的数据
指定时间节点前2小时交易记录的SQL正确写法
现有写法的问题
首先明确核心需求:筛选固定时间点2019-11-20 18:00:00往前2小时区间内的交易记录,对应时间范围为2019-11-20 16:00:00 至 2019-11-20 18:00:00。
你最初写的SQL存在两个明显问题:
- 调用
getdate()取当前系统时间作为筛选节点,和你需要的固定时间节点筛选要求不符 - SELECT子句中
START_DTTM字段后多了冗余逗号,会触发语法错误
后续调整的两种写法也都存在逻辑缺陷:
- 采用
between ... and ...的写法:BETWEEN为闭区间匹配,会同时包含区间两端的边界值,也就是会把18:00:00整发生的交易计入结果。如果你的需求是取「18:00:00之前」的记录,这种写法会多算边界数据。另外如果START_DTTM字段是带毫秒/微秒精度的时间类型,闭区间写法容易出现精度匹配导致的漏数问题。 - 仅用大于运算符的写法:只设置了16:00:00的下限条件,没有加18:00:00的上限约束,会返回所有16:00:00之后的交易(包括18:00之后的所有数据),所以返回200条远超基准记录数,完全不符合筛选要求。
最优写法推荐
推荐使用半开区间写法明确约束上下限,既避免边界歧义,也不会出现无上限导致的结果冗余,写法如下:
SELECT DISTINCT ID, START_DTTM FROM table1 WHERE START_DTTM >= DATEADD(HOUR, -2, CAST('2019-11-20 18:00:00' AS DATETIME)) AND START_DTTM < CAST('2019-11-20 18:00:00' AS DATETIME);
写法说明
- 下限用
>=:包含16:00:00整的交易记录,不会漏算区间起点数据 - 上限用
<:不包含18:00:00整的记录,完全匹配「18:00:00之前2小时」的需求,同时可以覆盖17:59:59.999及之前所有精度的时间值,不会因为时间字段精度问题漏数 - 如果业务规则要求必须包含18:00:00整的交易,只需要把上限条件的
<替换为<=即可。
内容的提问来源于stack exchange,提问作者adey27
相关产品推荐
相关产品推荐

