在postgreSQL中一天超过24小时

rap*_*2-h 10 sql postgresql intervals

假设我有这个架构:

create table rental (
    id           integer,
    rental_date  timestamp,
    customer_id  smallint,
    return_date  timestamp,
);
Run Code Online (Sandbox Code Playgroud)

运行此查询返回奇怪的结果:

select customer_id, avg(return_date - rental_date) as "avg"
from rental
group by customer_id
order by "avg" DESC
Run Code Online (Sandbox Code Playgroud)

它显示:

customer_id|avg_rent_duration     |
-----------|----------------------|
        315|     6 days 14:13:22.5|
        187|5 days 34:58:38.571428|
        321|5 days 32:56:32.727273|
        539|5 days 31:39:57.272727|
        436|       5 days 31:09:46|
        532|5 days 30:59:34.838709|
        427|       5 days 29:27:05|
        555|5 days 26:48:35.294118|
...

599 rows
Run Code Online (Sandbox Code Playgroud)

为什么会出现像值5 days 34:58:385 days 32:56:32等等?我以为一天只有24小时在那儿,也许我错了。

编辑

演示在这里:http : //sqlfiddle.com/#!17/caa7a/1/0

样本数据:

insert into rental (rental_date, customer_id, return_date)
values
('2007-01-02 13:10:06', 1, '2007-01-03 01:01:01'),
('2007-01-02 01:01:01', 1, '2007-01-09 15:10:06'),
('2007-01-10 22:10:06', 1, '2007-01-11 01:01:01'),
('2007-01-30 01:01:01', 1, '2007-02-03 22:10:06');
Run Code Online (Sandbox Code Playgroud)

rap*_*2-h 8

您必须使用justify_interval()功能调整间隔:

select customer_id, justify_interval(avg(return_date - rental_date)) as "avg"
from rental
group by customer_id
order by "avg" DESC;
Run Code Online (Sandbox Code Playgroud)

请参阅官方文档

使用justify_days和调整间隔justify_hours,并进行额外的符号调整

尽管如此,它并不能解释为什么在不使用的情况下操作结果会那么奇怪justify_interval()(换句话说,为什么我们必须应用这个函数)

注意:感谢@a_horse_with_no_name评论


Lau*_*lbe 5

这是试图解释这种行为。

PostgreSQL 间隔在间隔运算期间不会得到超出必要范围的“合理化”。我想说有两个原因:

  • 速度
  • 失去精确性(例如,当天数按月转换时,假设一个月有 30 天

所以你会得到这样的结果:

SELECT INTERVAL '1 day 20 hours' + INTERVAL '5 days 30 hours';

    ?column?     
-----------------
 6 days 50:00:00
(1 row)
Run Code Online (Sandbox Code Playgroud)

对于除法也是如此:

SELECT INTERVAL '6 days 50 hours' / 2;

    ?column?     
-----------------
 3 days 25:00:00
(1 row)
Run Code Online (Sandbox Code Playgroud)

总是将时间调整为小于 24 会使avg您正在计算的冗长计算变得不必要地复杂,并且正如您所发现的,有一些函数可以调整结果。