有没有可靠的方法从 postgres 间隔中提取年份?

Tom*_*m G 7 postgresql

在 Postgres 中,如果我执行以下操作:

select (now() - created_at) from my_table
Run Code Online (Sandbox Code Playgroud)

我得到这样的结果:

854 days 12:04:50.29658
Run Code Online (Sandbox Code Playgroud)

然而,如果我这样做:

select age(now(), created_at) fro my_table
Run Code Online (Sandbox Code Playgroud)

我得到这样的结果:

2 years 4 mons 3 days 12:04:50.29658
Run Code Online (Sandbox Code Playgroud)

根据pg_typeof(...)他们都是类型interval

但如果我尝试提取年份:

select extract(years from age(now(), created_at)) from my_table
Run Code Online (Sandbox Code Playgroud)

我得到:

2
Run Code Online (Sandbox Code Playgroud)

鉴于:

select extract(years from (now() - created_at)) from my_table
Run Code Online (Sandbox Code Playgroud)

我得到:

0
Run Code Online (Sandbox Code Playgroud)

是否有一致的方法从间隔值中提取年数(无论它是如何生成的)?

注意:我没有对数据库的写访问权限,因此无法定义存储过程等。需要是一个 select 语句。

- - -更新- - -

justify_interval(...)下面提出了建议,但不幸的是它的计算似乎不准确。

例如:

select age('2018-01-03'::timestamp, '2016-01-05'::timestamp);
Run Code Online (Sandbox Code Playgroud)

给出正确答案:

1 year 11 mons 29 days
Run Code Online (Sandbox Code Playgroud)

然而:

select justify_interval('2018-01-03'::timestamp - '2016-01-05'::timestamp);
Run Code Online (Sandbox Code Playgroud)

给出:

2 years 9 days
Run Code Online (Sandbox Code Playgroud)

我相信这是因为它(错误地)假设所有月份都有 30 天

(参见justify_days 此处: https: //www.postgresql.org/docs/current/static/functions-datetime.html

Lau*_*lbe 2

该函数justify_interval执行您想要的操作。结合使用它EXTRACT可以得到年份:

SELECT EXTRACT(years FROM
               justify_interval(INTERVAL '1 year 900 days 700 hours'));
 date_part 
-----------
         3
(1 row)
Run Code Online (Sandbox Code Playgroud)

如果 30 天 = 1 个月对您来说不够准确,您必须使用EXTRACT来获取天数并除以 365.25。

理论上,精确度是有限制的,因为间隔的年数在某种程度上取决于该间隔的日期

二元素age函数给出两个日期之间的年数的精确结果。