Trino/Presto 上的这段代码表示日差是 22:
with period as (
select
timestamp '2017-01-09 10:49:49' as period_start,
timestamp '2017-02-01 07:02:32' as period_end
)
select date_diff('day', period_start, period_end) as duration_days
from period
雪花说23:
with period as (
select
timestamp '2017-01-09 10:49:49' as period_start,
timestamp '2017-02-01 07:02:32' as period_end
)
select datediff(day, period_start, period_end) as duration_days
from period;
为什么
datediff
的结果不同?
(来源:与客户的对话)
问题的更一般形式是 Snowflake 采用更简单的方法,并回答
date_diff
的所有单位的比较单位值的差异。
与真实值差异进行比较,然后以时间单位表示。
雪花的作用:
unit_answer = TRUNC( unit, to_date ) - TRUNC( unit, from_date);
相比:
unit_answer TRUNC( unit, to_date - from_date);
对于像分钟、小时、天这样的简单跨度,以太可以工作(尽管可能不是你期望的那样),但是一旦你查看年/月,一年中有多少天的基本单位。一个月中有许多基本单位的天数(28,29,30,31)??。所以雪花之道有优点。我只是相信这不是大多数人所期待的一流公民日期时间视角。
2021年12月31日23:59:59和2022年1月1日00:00:01是2秒部分,但也相隔1个月和1年。
如果计算不同天数,日期差异为 23。
我猜测 Trino 还会查看两个时间戳之间的小时数差异,以在小于 24 小时的情况下得出近似结果。
只要时间戳处于不同的日期,Snowflake 就会将天数差异计为 1,即使午夜之间只有 2 秒:
select timediff(day, '2017-01-09 23:59:59', '2017-01-10 00:00:01')
-- 1
Snowflake 的实现似乎与大多数其他实现一致,因为大多数人都关心跨越边界。
基于 Simeon 的出色答案,您可以在 Trino (Presto) 中获得与 Snowflake 和其他类似的行为相同的行为:
with period as (
select
timestamp '2017-01-09 10:49:49' as period_start,
timestamp '2017-02-01 07:02:32' as period_end
)
select date_diff('day',
date_trunc('day', period_start),
date_trunc('day', period_end)
) as duration_days
from period