如何在Snowflake的CASE语句中正确使用DATEADD函数?
问题根因
- 类型不匹配:CASE 表达式要求所有返回分支的数据类型必须一致,你写的语句中
THEN 0返回数字类型,ELSE DATEADD(...)返回 datetime 类型,两类数据无法兼容,直接导致数据库抛出报错。 - 逻辑歧义:
FINAL_DATETIME是 datetime 类型,数字0无法直接作为合法的日期值写入该字段,你需要先明确转换失败时的默认逻辑:是直接取FIRST_DATETIME(等同于加0天),还是指定一个固定的默认日期(比如'1970-01-01'这类合法日期值)。
修正方案
方案1:转换失败时默认取FIRST_DATETIME(等同于加0天)
这是最符合常规业务逻辑的处理方式,修正后语句如下:
select ID, PERIOD_DAYS, FIRST_DATETIME, case when try_to_number(PERIOD_DAYS) IS NULL then FIRST_DATETIME else DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME) END as FINAL_DATETIME from TBL_A a group by ID,PERIOD_DAYS,FIRST_DATETIME, case when try_to_number(PERIOD_DAYS) IS NULL then FIRST_DATETIME else DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME) END
如果你的数据库支持GROUP BY直接引用SELECT定义的别名,可以简化为:
select ID, PERIOD_DAYS, FIRST_DATETIME, case when try_to_number(PERIOD_DAYS) IS NULL then FIRST_DATETIME else DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME) END as FINAL_DATETIME from TBL_A a group by ID,PERIOD_DAYS,FIRST_DATETIME,FINAL_DATETIME
方案2:转换失败时指定固定默认日期
如果你需要用特殊日期做标记,比如默认返回1970-01-01,修改THEN分支的返回值为对应日期常量即可:
select ID, PERIOD_DAYS, FIRST_DATETIME, case when try_to_number(PERIOD_DAYS) IS NULL then '1970-01-01'::datetime else DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME) END as FINAL_DATETIME from TBL_A a group by ID,PERIOD_DAYS,FIRST_DATETIME, case when try_to_number(PERIOD_DAYS) IS NULL then '1970-01-01'::datetime else DATEADD('days',try_to_number(PERIOD_DAYS), FIRST_DATETIME) END
内容的提问来源于stack exchange,提问作者lalaland
相关产品推荐
相关产品推荐

