2012-01-28 90 views
0

我有一个数据集(以.tsv格式)其中一列是出生日期。但是,数据是旧的,并不是所有的日期格式都是YYYY-MM-DD。有些参赛作品的出生年份(出生月份和出生日期均已丢失),格式为YYYY-##-##(字面上##已插入数据,只有已知年份)。我希望将此数据集加载到我的postgres数据库中,其中出生日期列的数据类型为date,而不是string,以便我可以对日期进行比较。
下面显示了一个小样本。 (数据的不相关的列未示出)Postgresql日期格式

1924-##-## 
1965-09-04 
1944-11-05 
1951-##-## 
-388-##-## 
1893-01-26 
1037-##-## 

直接批量加载数据集明显给出错误

ERROR: invalid input syntax for type date: "1924-##-##" 
LINE 1: insert into d values ('1924-##-##'); 
          ^

对数据集进行相当大的,具有约6亿卢比条目。目前我正在考虑运行一个脚本,用01替换这些##的脚本,然后将修改后的数据插入到数据库中。但我不喜欢这个想法 -

  1. 这是非常耗时的。
  2. 这是磁盘空间消耗(因为我想保留原始的“umtampered”数据)
  3. 此外,并非所有的数据在我的数据库中都是真实的。

有没有什么办法可以让postgres以某种方式把日期变成现实,只是忽略了##(s)(并且只保留了几个月和几天都没有的年份)呢?
或者有没有更好的解决方案来解决这个问题?

回答

0

你在这里

  1. 两个选项一旦你从数据库读取数据,更换#中出现的所有服务器端脚本,然后比较的日期。 (您也可以在表格中动态替换数据,而无需在查询中使用if条件修改现有数据)
  2. 忽略具有#的日期。这样你可以比较只有有效的日期。
0

如果您需要保留#个字符,我所看到的唯一机会是将其导入varchar列。

如果您绝对需要这些信息作为日期,那么您可能会忽略转换的视图,并且只会选择列中没有#的那些行。

喜欢的东西

SELECT to_date(dob,'YYYY-MM-DD') as dob_date 
FROM your_table 
WHERE substr(dob,6,2) <> '##'; 

如果你这样做定期,你可能要考虑对表达的索引,以加快选择:

CREATE INDEX dob_check ON your_table(substr(dob,6,2)); 

注意的是,在表达您的选择必须匹配,确切地说索引中的表达式才能被查询平面器使用。

如果您希望将数据“转换”为检索过程中有效的日期,你可以做这样的事情:

SELECT case 
     case when substr(dob,6,2) = '##' then to_date(substr(dob,1,5)||'01-01', 'YYYY-MM-DD') 
     else to_date(dob,'YYYY-MM-DD') 
     end as dob_date 
FROM your_table; 
1

您可以在表中创建两列,一个原先输入的值(类型的varchar)和一个用于计算(键入日期)。

CREATE TABLE your_table 
(
id INT, 
-- OTHER DETAILS 
dob_entered VARCHAR, 
dob_parsed DATE 
); 

然后可以使用上一个INSERT触发器从VARCHAR自动填充日期字段,通过更新触发器来处理任何变化。

CREATE OR REPLACE FUNCTION evaluate_dob_date() RETURNS TRIGGER AS 
$$ 
BEGIN 
    NEW.dob_parsed = CAST(REPLACE(NEW.dob_entered,'##','01') AS DATE); 
    RETURN new; 
END; 
$$ 
LANGUAGE plpgsql; 

CREATE TRIGGER parse_dob 
BEFORE INSERT OR UPDATE ON your_table 
FOR EACH ROW 
EXECUTE PROCEDURE evaluate_dob_date(); 

这将意味着你同时存储不变核实原先输入的数据,同时还具有在数据库中适合进行排序和比较等。另外一个日期字段,通过扩展evaluate_dob_date()功能可以匹配针对不同但是仍然能够拒绝真正无效的记录。

Postgresql triggers

+0

Upvoted但只是一个小附记,你实际上并没有存储date_parsed。你可以做一些类似table的方法,然后限制它的输出,所以你知道你的输入日期总是被解析。有关表格方法的更多信息,请参阅我写的这篇博客文章:http://ledgersmbdev.blogspot.com/2012/08/postgresql-or-modelling-part-2-intro-to.html – 2012-09-08 05:15:35