一天超过 24 小时在 postgreSQL 中
More than 24 hours in a day in postgreSQL
假设我有这个架构:
create table rental (
id integer,
rental_date timestamp,
customer_id smallint,
return_date timestamp,
);
运行 这个查询 returns 奇怪的结果:
select customer_id, avg(return_date - rental_date) as "avg"
from rental
group by customer_id
order by "avg" DESC
显示:
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
为什么会有5 days 34:58:38
、5 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');
您必须使用 justify_interval()
函数调整间隔:
select customer_id, justify_interval(avg(return_date - rental_date)) as "avg"
from rental
group by customer_id
order by "avg" DESC;
Adjust interval using justify_days
and justify_hours
, with additional sign adjustments
仍然没有解释为什么不使用justify_interval()
操作的结果是那么奇怪(换句话说,为什么我们必须应用这个功能)
注:感谢@a_horse_with_no_name for their
这是对行为的解释。
PostgreSQL 区间在区间运算期间没有得到比必要的更多的“合理化”。我会说这有两个原因:
- 速度
- 不准确(例如,当天数按月转换时,假设一个月有 30 天
所以你得到这样的结果:
SELECT INTERVAL '1 day 20 hours' + INTERVAL '5 days 30 hours';
?column?
-----------------
6 days 50:00:00
(1 row)
除法同理:
SELECT INTERVAL '6 days 50 hours' / 2;
?column?
-----------------
3 days 25:00:00
(1 row)
总是将小时数调整为小于 24 会使像 avg
这样的长计算变得不必要地复杂,正如您所发现的,有调整结果的函数。
假设我有这个架构:
create table rental (
id integer,
rental_date timestamp,
customer_id smallint,
return_date timestamp,
);
运行 这个查询 returns 奇怪的结果:
select customer_id, avg(return_date - rental_date) as "avg"
from rental
group by customer_id
order by "avg" DESC
显示:
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
为什么会有5 days 34:58:38
、5 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');
您必须使用 justify_interval()
函数调整间隔:
select customer_id, justify_interval(avg(return_date - rental_date)) as "avg"
from rental
group by customer_id
order by "avg" DESC;
Adjust interval using
justify_days
andjustify_hours
, with additional sign adjustments
仍然没有解释为什么不使用justify_interval()
操作的结果是那么奇怪(换句话说,为什么我们必须应用这个功能)
注:感谢@a_horse_with_no_name for their
这是对行为的解释。
PostgreSQL 区间在区间运算期间没有得到比必要的更多的“合理化”。我会说这有两个原因:
- 速度
- 不准确(例如,当天数按月转换时,假设一个月有 30 天
所以你得到这样的结果:
SELECT INTERVAL '1 day 20 hours' + INTERVAL '5 days 30 hours';
?column?
-----------------
6 days 50:00:00
(1 row)
除法同理:
SELECT INTERVAL '6 days 50 hours' / 2;
?column?
-----------------
3 days 25:00:00
(1 row)
总是将小时数调整为小于 24 会使像 avg
这样的长计算变得不必要地复杂,正如您所发现的,有调整结果的函数。