2

我有一个带有列名的表description

description  //character varying
LZ000834_28-02-14
LZ000834_28-02-14
LA20683_30-04-15
LA20683_30-04-15
LA20300_31-01-15
LA20300_31-01-2015
LA20264_31-01-15
LA20264_31-01-2016
LAN2078_31-03-16
LAN2078_31-03-15
LAN8394_31-04-14
L2Z82736_31_03_2015  //has 1million rows

这里的描述是batchname_expirydate

我的问题是如何规范我的描述列将所有这些日期转换为DD-MM-YY格式

我试过这两个查询

select substring(description from position('_' in description) +1) from attributesetinstance;

上面的查询会给我所有的字符串然后我尝试这样的日期转换

select to_date(substring(description from position('_' in description) +1), 'DD-MM-YY') from attributesetinstance;

现在这给了我错误

ERROR:  invalid value "_3" for "DD"
DETAIL:  Value must be an integer.


********** Error **********

ERROR: invalid value "_3" for "DD"
SQL state: 22007
Detail: Value must be an integer.

如何更新/纠正我的所有数据库?

更新:

尝试使用另一个 sql

with product_dates AS (
select description, ((val[2])||'-'||val[3]||'-'||val[4])::date as expir_date
from ( 
    select description,regexp_matches(description, '([a-zA-Z0-9]+)_([0-9]+)[-_]([0-9]+)[-_]([0-9]+)') as val 
    from attributesetinstance
) a
), expiring_dates AS (
select description from product_dates
)
select description from expiring_dates

我收到以下错误:

ERROR:  date/time field value out of range: "31-04-14"


********** Error **********

ERROR: date/time field value out of range: "31-04-14"
SQL state: 22008

更新

我的 postgres 日期样式

show datestyle;
"ISO, DMY"
4

1 回答 1

1

此错误消息不好 - 此日期 2014-04-31 无效。因此,您不能使用您使用的算法将此字符串转换为日期。但是 to_date 函数是容错的

postgres=# select '2014-04-31'::date;
ERROR:  date/time field value out of range: "2014-04-31"
LINE 1: select '2014-04-31'::date;
               ^
Time: 0.551 ms
postgres=# select to_date('2014-04-31','YYYY-MM-DD');
  to_date   
────────────
 2014-05-01
(1 row)

此代码有效

 postgres=# select to_date(replace(substring('LA20683_30_04_15' from '\d+[-_]\d+[-_]\d+$'),'_','-'), 'DD-MM-YY');
  to_date   
────────────
 2015-04-30
(1 row)

Time: 57.840 ms
postgres=# select to_date(replace(substring('LA20683_30_04_2015' from '\d+[-_]\d+[-_]\d+$'),'_','-'), 'DD-MM-YY');
  to_date   
────────────
 2015-04-30
(1 row)

8.4 的解决方法:

CREATE OR REPLACE FUNCTION to_date_DD_MM_YY_2_4(text)
RETURNS date AS $$
SELECT CASE WHEN $1 ~ e'\\d+-\\d+-\\d{2}$' THEN to_date($1, 'DD-MM-YY') 
                                           ELSE to_date($1, 'DD-MM-YYYY')
       END$$ 
LANGUAGE sql;
CREATE FUNCTION
Time: 25.229 ms

postgres=# SELECT to_date_DD_MM_YY_2_4('30-04-2015');
 to_date_dd_mm_yy_2_4 
----------------------
 2015-04-30
(1 row)
于 2013-12-08T09:25:49.653 回答