Snowflake中union拼接integer与varchar列输出decimal类型的原因问询
为什么UNION拼接integer和varchar类型列时输出为decimal
UNION/UNION ALL执行时要求所有分支的对应列类型必须兼容,数据库会自动做隐式类型转换,选择一个能无损容纳两边所有可能取值的公共类型作为最终输出列的类型:
- 当数值类型和字符串类型做匹配时,数据库会优先将字符串向数值类型转换(而非反过来把数值转成字符串,避免丢失数值的类型属性)
- decimal属于精确数值类型,取值范围和精度都远高于integer,既可以容纳所有integer的合法值,也能兼容大部分可转为数值的字符串内容(比如带小数的数字字符串、超长数字串,不会像转integer那样容易溢出),是两边类型的最优兼容选项,因此最终输出类型为decimal。
可参考的输出类型预测规则
主流关系型数据库的隐式类型转换基本遵循统一的优先级逻辑,优先级从高到低大致如下,最终输出会选用优先级更高的兼容类型:
- 高精度数值类型 > 低精度数值类型:
decimal > bigint > int > smallint > tinyint - 数值类型 > 字符串类型:数值和字符串匹配时,优先选择兼容的数值类公共类型
- 长字符类型 > 短字符类型:同为字符串时,最终输出长度取两边的最大长度
- 可空类型优先级高于非空类型:只要其中一列允许为空,最终输出列就为可空类型
注意:如果待转换的字符串内容不是合法数值(比如包含非数字字符),类型转换会直接报错;不同数据库的优先级规则会有细微差异,特殊场景下建议参考对应数据库的官方类型转换文档。
复现脚本
你可以通过以下SQL复现该行为:
select typeof(ID) from ( SELECT '12345'::integer ID UNION ALL SELECT '12345'::varchar ID ) as lt;
运行后返回的ID类型为decimal。
内容的提问来源于stack exchange,提问作者user2588792
相关产品推荐
相关产品推荐

