Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql日期格式_Postgresql_Date_Formatting_Postgresql 8.4 - Fatal编程技术网

Postgresql日期格式

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

我有一个.tsv格式的数据集,其中一列是出生日期。但是,数据是旧的,并非所有日期都是YYYY-MM-DD格式。有些条目只是缺少出生年份、月份和出生日期,并且格式为YYYY——在只知道年份的地方,字面上的已插入数据中。我希望将此数据集加载到我的postgres数据库中,数据类型为date而不是string的date of birth列,以便我可以对日期进行比较。 下面是一个小样本。不显示不相关的数据列

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();