INTERVAL '1' DAY是否始终等价于INTERVAL '24' HOURS?SQL标准解析
1天 vs 24小时:SQL标准与数据库实现差异
直观上我们总觉得“1天”和“24小时”是一回事,但碰到夏令时变更的场景,这个认知就得打个问号了——春季夏令时开始时,“1天”可能只有23小时,秋季夏令时结束时则会变成25小时。
我专门在PostgreSQL里做了测试,结果证实这两者确实不等价。执行这段SQL:
set timezone TO 'CET'; SELECT timestamp with time zone'2020-03-29 0:00 Europe/Bratislava' + INTERVAL '1' DAY, timestamp with time zone'2020-03-29 0:00 Europe/Bratislava' + INTERVAL '24' HOUR;
客户端时区设为UTC的话,返回结果是2020-03-29T22:00:00.000Z和2020-03-29T23:00:00.000Z,明显差了一小时。
再看看其他主流数据库的表现:
- MySQL:只支持时区偏移量,不处理夏令时变更逻辑,所以“1天”永远等于24小时。
- Apache Calcite(支撑Drill、Flink等SQL实现):会把日间隔转成毫秒计算,默认按24小时=1天来处理。
- Oracle:测试了同样的场景——给
2020-03-29 0:00 CET加1天或24小时,结果完全一致。 - SQL Server、DB2:和MySQL类似,仅支持时区偏移量,所以两者等价。
哪种处理符合SQL标准?
根据SQL:2011及后续版本的标准定义,INTERVAL '1' DAY和INTERVAL '24' HOUR在涉及夏令时的时区中是允许不等价的。标准里明确区分了两种间隔:
- 基于日期的间隔(比如DAY)是按日历日期计算的:添加1天意味着跳到下一个日历日的同一时间点,哪怕夏令时切换导致实际时长不是24小时;
- 基于小时的间隔是按绝对时长计算的:添加24小时就是严格累加24个小时,不管日历日期怎么变。
所以PostgreSQL的实现是完全符合SQL标准的,其他数据库要么是因为不支持夏令时处理,要么是做了简化,才会让两者看起来等价。
内容的提问来源于stack exchange,提问作者Oliv
相关产品推荐
相关产品推荐

