postgresql - 在 postgres 中标准化日期 - 迄今为止的字符

标签 postgresql date substring trim to-date

我有一个列名 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"

最佳答案

这个错误信息不好——这个日期 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)

关于postgresql - 在 postgres 中标准化日期 - 迄今为止的字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20450942/

相关文章:

sql - 试图过滤别名列中的空值 - postgresql?

sql - 将文件插入 Postgres 数据库

mysql - 如何在 WebService 调用中使用 %20 而不在 UITextField 中显示它

mysql - 使用 REPLACE 和 SUBSTRING_INDEX 在 MySQL 中拆分字符串

java - 大字符串中最长的重复且不重叠的子字符串

sql - Postgres 条件选择?

arrays - 我什么时候应该使用数组列 vs. rails 协会

php - 在 PHP 中处理在不同时区存储/显示日期的最佳方法?

java - 在 java.time (Java 8) 中正确地将时间转换为毫秒

c - 从C中的一行中读取带有空格的子字符串