如何在Snowflake中正确存储带正负标识的时区偏移值
问题原因
Snowflake的+运算符不支持VARCHAR类型的时间格式字符串和整数直接做间隔运算。原SQL中第一个CASE返回的是HH:MM/-HH:MM格式的字符串,第二个CASE返回的是整数,二者相加时Snowflake会默认尝试把两侧值都转为数值类型计算,带冒号的字符串无法转成数值,就会抛出识别错误。
Teradata中是通过显式声明Interval hour to minute类型把字符串转为时间间隔类型再做运算,Snowflake没有完全等价的隐式间隔转换逻辑,直接照搬写法会触发类型不匹配问题。
实现方案
由于需要叠加的是整24小时偏移,分钟值不会发生变化,不需要做复杂的时间类型转换,直接将小时、分钟、偏移量拆成整数计算后再拼接成目标字符串即可,从根源避免类型转换错误,逻辑和Teradata完全对齐:
SELECT CONCAT( tz_sign, LPAD(ABS(tz_hour) + add_hour_offset, 2, '0'), ':', LPAD(tz_minute, 2, '0') ) AS COLUMN_1 FROM ( SELECT SUBSTR(raw_data, 48, 1) AS tz_sign, CAST(SUBSTR(raw_data, 49, 2) AS INT) AS tz_hour, CAST(SUBSTR(raw_data, 51, 2) AS INT) AS tz_minute, CASE WHEN SUBSTR(raw_data, 40, 4) = '2400' THEN 24 ELSE 0 END AS add_hour_offset FROM ( SELECT temp_row.$1 AS raw_data FROM @JOB_MANAGEMENT.SNOWFALKE ( file_format => 'DB.TBL_FILE_FORMAT', pattern=>'.*/input_file.txt' ) temp_table ) );
逻辑说明
- 完全保留原SQL中所有字段截取位置,不需要调整偏移量取值规则
- 符号位单独提取拼接,避免正负号参与数值计算
- 小时、分钟、24小时偏移全部转为整数计算,不会触发隐式类型转换报错
- 用
LPAD补前导零,保证小时、分钟始终为2位,符合±HH:MM的格式要求 - 最终返回值为VARCHAR类型,可以直接写入目标字段
- 如果业务要求叠加24小时后小时值按24小时取模(例如叠加24小时后偏移值与原值一致、负偏移计算后转正数),只需将小时计算部分替换为
MOD(ABS(tz_hour) + add_hour_offset, 24)即可。
内容的提问来源于stack exchange,提问作者Rocky1989
相关产品推荐
相关产品推荐

