You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL求和时间跨度时为何未完全转换单位?

为什么PostgreSQL求和时间间隔时不把小时完全转换为天?

问题背景

我创建了如下结构的room_server_metrics表:

create table room_server_metrics (
  namespace  varchar(36) not null,
  session_id varchar(36) not null,
  primary key (namespace, session_id),

  created_at timestamptz   not null default now(),
  updated_at timestamptz   not null default now(),
);

当统计所有会话总时长时,执行以下查询得到结果:

database=> select sum(updated_at - created_at) as total_time from room_server_metrics;
         total_time         
----------------------------
 94 days 60951:01:56.381483

计算后发现94天加60951小时约等于2633天,但直接以秒为单位输出时:

database=> select extract(epoch from sum(updated_at - created_at)) as total_time from room_server_metrics;
         total_time         
----------------------------
 227546617.181704

该秒数同样约等于2633天,疑惑为何第一个查询未将超过94天的小时数完全转换为天单位?

原因解释

这是PostgreSQL对interval类型求和的默认行为:它会分别累加时间间隔的各个字段(天、小时、分钟、秒等),而不会自动将低位字段(如小时)进位到高位字段(如天)。

比如两个会话时长分别是1 day 25:00:00和2 days 23:00:00,求和后会直接得到3 days 48:00:00,而非自动把48小时转换成2天得到5 days 00:00:00。你查询里的60951小时就是所有会话的小时字段直接相加的结果,没有做进位处理。

解决方法

如果想要得到完全进位后的规整时间格式,可以使用PostgreSQL的justify_interval函数,它会自动将所有时间字段进位到合理的单位:

select justify_interval(sum(updated_at - created_at)) as total_time from room_server_metrics;

执行后,60951小时会被转换成2539 days 15:00:00,加上原有的94天,最终结果会显示为2633 days 15:01:56.381483,和秒数计算的结果一致。

另外也可以先转成秒再计算成天:

select sum(extract(epoch from (updated_at - created_at))) / 86400 as total_days from room_server_metrics;

内容的提问来源于stack exchange,提问作者mxweas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:42:40