我有一个查询我在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]
-----------------------------------------------
答案 0 :(得分:0)
不是将日期转换为人类可读的YYYYMMDD
格式,最好将它们保持为DATE
或TIMESTAMP
格式。这样,可以容易地执行日期操作(例如,将日期添加5天)。您仍然可以使用'YYYYMMDD'::DATE
进行简单的比较运算符。
鉴于您正在从String转换,并且转换为Date似乎有效,并且您有一些空字符串,请使用此字符串将其转换为日期:
SELECT
NULLIF(start_dttm, '')::DATE AS dt
FROM sfe.calendar_detail
WHERE dt > '20170920'::DATE
如果字符串为空,则返回NULL;如果包含可以转换的日期,则返回Date。