Postgresql日期格式
我有一个.tsv格式的数据集,其中一列是出生日期。但是,数据是旧的,并非所有日期都是YYYY-MM-DD格式。有些条目只是缺少出生年份、月份和出生日期,并且格式为YYYY——在只知道年份的地方,字面上的已插入数据中。我希望将此数据集加载到我的postgres数据库中,数据类型为date而不是string的date of birth列,以便我可以对日期进行比较。 下面是一个小样本。不显示不相关的数据列Postgresql日期格式,postgresql,date,formatting,postgresql-8.4,Postgresql,Date,Formatting,Postgresql 8.4,我有一个.tsv格式的数据集,其中一列是出生日期。但是,数据是旧的,并非所有日期都是YYYY-MM-DD格式。有些条目只是缺少出生年份、月份和出生日期,并且格式为YYYY——在只知道年份的地方,字面上的已插入数据中。我希望将此数据集加载到我的postgres数据库中,数据类型为date而不是string的date of birth列,以便我可以对日期进行比较。 下面是一个小样本。不显示不相关的数据列 1924-##-## 1965-09-04 1944-11-05 1951-##-## -388
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替换这些,然后将修改后的数据插入数据库。但我不喜欢这个主意-
这很费时。
这是磁盘空间消耗,因为我想保留原始被篡改的数据
而且,我的数据库中并非所有数据都是真实的。
有没有什么办法可以让博士后们把日期保持原样,忽略“s”而只保留缺少月份和天数的年份?
或者有更好的解决方法吗?这里有两种选择 从数据库获取数据后,替换服务器端脚本中出现的所有数据,然后比较日期。您还可以动态替换表本身中的数据,而无需在查询中使用if条件修改现有数据 忽略具有相同日期的日期。这样,您只能比较有效日期。 如果需要保留字符,我看到的唯一机会就是将其导入varchar列 如果您确实需要这些信息作为日期,那么可以使用一个进行转换的视图,只选择列中没有的行 差不多
SELECT to_date(dob,'YYYY-MM-DD') as dob_date
FROM your_table
WHERE substr(dob,6,2) <> '##';
请注意,select中的表达式必须与索引中的表达式完全匹配,才能供查询规划器使用
如果要在检索期间将数据转换为有效日期,可以执行以下操作:
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;
您可以在表中创建两列,一列用于最初输入的varchar值类型,另一列用于计算类型date
CREATE TABLE your_table
(
id INT,
-- OTHER DETAILS
dob_entered VARCHAR,
dob_parsed DATE
);
然后,您可以使用插入触发器自动填充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函数,您可以根据发现的不同情况进行匹配,同时仍然能够拒绝真正无效的记录
向上投票,但只是一个小的附加说明,您实际上不必存储解析的日期。您可以做一些类似于表方法的事情,然后约束该方法的输出,这样您就知道输入日期总是解析的。有关表方法的更多信息,请参阅我写的这篇博客文章:
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();