Snowflake SQL中使用日期过滤Timestamp字段的异常问题咨询
核心原因:时区隐式转换 + BETWEEN的闭区间特性
当你在WHERE子句中使用timestamp BETWEEN 'YYYY-MM-DD' AND 'YYYY-MM-DD'时,Snowflake会自动将日期字符串转换为当前会话时区的午夜0点时间戳,而BETWEEN是闭区间(包含两端点),时区差异会直接导致边界判断不符合预期。
对你测试场景的具体分析
使用
BETWEEN '2023-04-01' AND '2023-04-10'时仅返回1条记录
那条凌晨3点的记录,其timestamp值转换为会话时区后,恰好落在2023-04-01 00:00:00到2023-04-10 00:00:00的闭区间内;而当天其他14条记录的timestamp转换为会话时区后,都晚于2023-04-10 00:00:00,因此被排除。
举个实际例子:如果你的会话时区是UTC,而记录的timestamp带UTC+8时区,那么'2023-04-10'会被转成2023-04-10 00:00:00 UTC,对应UTC+8的时间是2023-04-10 08:00:00。UTC+8的2023-04-10凌晨3点记录,转换为UTC是2023-04-09 19:00:00,在区间内;而UTC+8当天08:00之后的记录,转换为UTC都在2023-04-10 00:00之后,超出了结束边界,所以不被返回。使用
BETWEEN '2023-04-01' AND '2023-04-11'时2023-04-10记录全显,但2023-04-11无记录
此时结束时间被转成2023-04-11 00:00:00(会话时区),对应你记录的时区来说,刚好覆盖2023-04-10全天的所有时间;而2023-04-11的记录转换为会话时区后,都晚于2023-04-11 00:00:00,因此被排除。
更稳妥的写法建议
除了你提到的'2023-04-10 23:59:59',更推荐使用半开区间避免时区和边界问题:
WHERE timestamp >= '2023-04-01' AND timestamp < '2023-04-11'
这种写法明确包含起始日期的所有时间,且不包含结束日期的任何时间,无需考虑时区转换带来的午夜边界问题,逻辑更清晰。
内容的提问来源于stack exchange,提问作者da_sha

