2013-12-08 212 views
2

我有一個表coloumnname 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. 

如何更新/ recorrect我所有的數據庫?

更新:

試圖與另一個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" 

回答

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) 
+0

我需要在'DD-MM-YY'格式的所有expirydates和Postgres的8.4我使用,它劑量明白'\ d' –

+0

'select to_date(替換(substring('LA20683_30_04_2015'from'[0-9] + [-_] [0-9] + [-_] [0-9] + $ '),'_',' - '),'DD-MM-YY');'給我這個答案''3915-04-30「' –

+0

你有可能使用8.4〜\\ d的雙反斜槓。但很奇怪 - 在9.4我得到了一個正確的答案。是的,8.4上有一個錯誤。它對模式的錯誤不太寬容。 –