2017-09-20 259 views
0

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

为了解决问题,我预先选择了非空字符串的日期,并将其转换为日期,然后转换为整数日期格式(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

@ 500-InternalServerError最大值是99991231,这小于redshift doc站点的最大值2147483647 – lucas

回答

0

而不是转换日期人类可读的格式YYYYMMDD,它始终是更好地保持他们的DATETIMESTAMP格式。这样,日期操作可以很容易地执行(例如,添加日期为5天)。通过使用'YYYYMMDD'::DATE,您仍然可以轻松地进行比较操作。

既然你是从一个字符串转换,并且转换成一时间似乎工作,和你有一些空字符串,用这个将其转换为一个日期:

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

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