将 VARCHAR 值转换为格式化日期,忽略错误

Convert a VARCHAR value to a formatted date, ignoring errors

我有一列包含 yyyy-mm-dd 格式的日期。现在我是 运行 一个 SELECT 查询,它使用 TO_CHAR(dob :: DATE, 'dd/mm/yyyy') AS dob 将该日期转换为 dd/mm/yyyy,效果很好。现在我遇到的问题是该列中有一些错误记录,下面是一个示例 table 有一个好的记录和一个错误的记录:

| id |    dob     |
|----|------------|
|  1 | 2019-12-31 | // this returns 31/12/2019
|  2 | 31-12-2019 | // BAD RECORD, this returns an error
|----|------------|

我在 id 2 上得到的错误是:

ERROR:  date/time field value out of range: "31-12-2019"
HINT:  Perhaps you need a different "datestyle" setting.
SQL state: 22008

我想要的是有条件地检查 TO_CHAR(dob :: DATE, 'dd/mm/yyyy') 是否正常,否则只需使用 dob 而不进行转换。有什么方法可以实现吗?

我正在使用 Postges 12

将日期存储为字符串不是一个好习惯,你的问题证明了这一点。
如果您确定此列中格式为 YYYY-MM-DD 的所有值都是 有效日期 ,则使用运算符 LIKE:

CASE 
  WHEN dob LIKE '____-__-__' THEN TO_CHAR(dob::DATE, 'dd/mm/yyyy') 
  ELSE dob
END AS dob

我能够通过创建一个类似于@a_horse_with_no_name > 发布的 link 中所选答案的函数来解决这个问题。函数:

create or replace function format_date_or_return_string(str varchar)
returns text language plpgsql as $$
begin
    return to_char(to_date(str, 'yyyy-mm-dd), 'dd-mm-yyyy');
exception
    when others then return str;
end $$;

因此 SELECT 将根据需要格式化好记录并忽略坏记录。

SELECT id, format_date_or_return_string(dob) 来自问题中的示例数据将 return:

| 1 | 31/12/2019 | // good record
| 2 | 31-12-2019 | // ignored bad record