Redshift 中的无效数据错误

Posted

技术标签:

【中文标题】Redshift 中的无效数据错误【英文标题】:Invalid data error in Redshift 【发布时间】:2017-09-20 17:28:23 【问题描述】:

我有一个在 redshift 中运行的查询,当我尝试比较两个日期时会产生错误。我已经确定这是由于日期为 VARCHAR 且有些为空字符串的数据问题。最好的解决方案显然是从源头上解决这个问题,但是在尝试解决这个问题时,我偶然发现了一些非常奇怪的行为。

为了解决问题,我预先选择了非空字符串的日期,并将其转换为日期,然后转换为整数日期格式 (YYYYMMDD) 并转换为 INT。这运行良好。但是,如果我尝试将其与 WHERE 子句中的整数进行比较,查询会因数据类型错误而崩溃。

这是工作查询的玩具版本

SELECT
    date_id,
    COUNT(*)
FROM
    (
    SELECT
        CONVERT(int, date_id) AS date_id
    FROM
        (
        SELECT
            DATE_PART('year', start_dttm)*10000+DATE_PART('month', start_dttm)*10+DATE_PART('day', start_dttm) AS date_id
        FROM        
            (
            SELECT
                CAST(start_dttm AS DATETIME) AS start_dttm
            FROM
                sfe.calendar_detail
            WHERE
                start_dttm <> ''
            ) cda
        ) cdb
    ) cd
GROUP BY
    date_id
;

这是失败的查询

SELECT
    date_id,
    COUNT(*)
FROM
    (
    SELECT
        CONVERT(int, date_id) AS date_id
    FROM
        (
        SELECT
            DATE_PART('year', start_dttm)*10000+DATE_PART('month', start_dttm)*10+DATE_PART('day', start_dttm) AS date_id
        FROM        
            (
            SELECT
                CAST(start_dttm AS DATETIME) AS start_dttm
            FROM
                sfe.calendar_detail
            WHERE
                start_dttm <> ''
            ) cda
        ) cdb
    ) cd
WHERE
    date_id >= 20170920
GROUP BY
    date_id
;

正如我上面提到的,正确的解决方案是修复数据类型并将空日期计为 Nulls 而不是空字符串,但我很好奇为什么第二个查询因无效数据类型错误而崩溃。

非常感谢!

编辑: 这是错误

ERROR:  Invalid digit, Value '1', Pos 0, Type: Integer 
DETAIL:  
  -----------------------------------------------
  error:  Invalid digit, Value '1', Pos 0, Type: Integer 
  code:      1207
  context:   
  query:     2006739
  location:  :0
  process:   query0_39 [pid=0]
  -----------------------------------------------

【问题讨论】:

@500-InternalServerError 最大值为 99991231,小于 redshift doc 站点的最大值 2147483647 【参考方案1】:

与其将日期转换为人类可读的YYYYMMDD 格式,不如将它们保留为DATETIMESTAMP 格式。这样,可以轻松执行日期操作(例如,将日期添加 5 天)。您仍然可以使用'YYYYMMDD'::DATE 进行简单的比较运算符。

鉴于您正在从字符串转换,并且转换为日期似乎有效,并且您有一些空字符串,请使用它来将其转换为日期:

SELECT
  NULLIF(start_dttm, '')::DATE AS dt
FROM sfe.calendar_detail
WHERE dt > '20170920'::DATE

如果字符串为空,则返回 NULL,如果包含可以转换的日期,则返回 Date。

【讨论】:

以上是关于Redshift 中的无效数据错误的主要内容,如果未能解决你的问题,请参考以下文章

从 Python 访问 Redshift 时出现“无效凭据”错误

Redshift 中的 DAU WAU MAU 错误:[Amazon](500310) 无效操作:由于内部错误,不支持此类关联子查询模式;

Redshift COPY 错误 1206 无效时间戳

如何清除 Amazon Redshift 中的以下语法错误

“错误:整数的输入语法无效:”在 Redshift 表中为 SMALLINT 列插入 NULL 值时?

1214:使用 COPY 命令将数据从 csv 导入 Redshift 时 CSV 的报价格式无效