在postgresql11.0中,将子串匹配提取的数字转换为年份

nbysray5  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(264)

在postgresql11.0中我有下表

min age      max age
1 Month      12 Months
1 Year       16 Years
1 Day        365 Days
365 Days     369 Days
N/A          N/A
NULL         NULL

我想把这些值转换成年份。我正在提取数字后面的字符串,检查它是'years'、'months'还是'days',然后将字符串前面的数字转换为year。
我尝试了以下查询:

update tbl
set min_age = 
        case 
                when substring(min_age, '^\d+\s(.*)') ~* 'Month'
                then abs(substring(min_age, '^(\d+)\s.*')/12)
                when substring(min_age, '^\d+\s(.*)') ~* 'Months'
                then abs(substring(min_age, '^(\d+)\s.*')/12)
                when substring(min_age, '^\d+\s(.*)') ~* 'Day'
                then abs(substring(min_age, '^(\d+)\s.*')/365)
                when substring(min_age, '^\d+\s(.*)') ~* 'Days'
                then abs(substring(min_age, '^(\d+)\s.*')/365)
                when substring(min_age, '^\d+\s(.*)') ~* 'Year'
                then abs(substring(min_age, '^(\d+)\s.*'))
                when substring(min_age, '^\d+\s(.*)') ~* 'Years'
                then abs(substring(min_age, '^(\d+)\s.*'))
        end ;

update tbl
set max_age = case
                when substring(min_age, '^\d+\s(.*)') ~* 'Month'
                then abs(substring(min_age, '^(\d+)\s.*')/12)
                when substring(min_age, '^\d+\s(.*)') ~* 'Months'
                then abs(substring(min_age, '^(\d+)\s.*')/12)
                when substring(min_age, '^\d+\s(.*)') ~* 'Day'
                then abs(substring(min_age, '^(\d+)\s.*')/365)
                when substring(min_age, '^\d+\s(.*)') ~* 'Days'
                then abs(substring(min_age, '^(\d+)\s.*')/365)
                when substring(min_age, '^\d+\s(.*)') ~* 'Year'
                then abs(substring(min_age, '^(\d+)\s.*'))
                when substring(min_age, '^\d+\s(.*)') ~* 'Years'
                then abs(substring(min_age, '^(\d+)\s.*'))
           end

预期输出为:

min age       max age
0             1
1             16
0             1
1             1
N/A           N/A
NULL          NULL

非常感谢您的帮助。

ifsvaxew

ifsvaxew1#

postgres具有强大的区间函数。我认为这是一个 cast 以及 justify_interval() 可能在这里工作:

select
    extract(year from justify_interval(min_age::interval)) min_age,   
    extract(year from justify_interval(max_age::interval)) max_age
from tbl

db小提琴演示:

min_yr | max_yr
:----- | :-----
0      | 1     
1      | 16    
0      | 1     
1      | 1
guykilcj

guykilcj2#

这就是如何获得所需的所有值:

select split_part(min_age, " ", 1) as min_age_value, split_part(min_age, " ", 2) as min_age_unit, split_part(max_age, " ", 1) as max_age_value, split_part(max_age, " ", 2) as max_age_unit
from tbl;

现在,您可以将上面的内容用作子字符串和用例,在外部查询中为min\u age\u unit和max\u age\u unit分别求值为1、12或365,并将其与实际值相乘。

相关问题