数据类型转换

在许多情况下,一种数据类型的值可以转换为另一种数据类型。例如,可以将 INTEGER 转换为 浮点数据类型。转换数据类型称为 类型转换

本主题内容:

显式类型转换与隐式类型转换

用户可以将值从一种数据类型显式转换为另一种数据类型。这称为 显式类型转换

在某些情况下,Snowflake 会自动将值转换为另一种数据类型。这称为 隐式类型转换强制转换

显式类型转换

用户可以使用以下任一选项显式转换值:

  • CAST 函数。

  • :: 运算符(称为 转换运算符)。

  • 适当的 SQL 函数(例如 TO_DOUBLE)。

例如:

SELECT CAST('2022-04-01' AS DATE);

SELECT '2022-04-01'::DATE;

SELECT TO_DATE('2022-04-01');
Copy

在允许使用一般表达式(包括 WHERE 子句)的大多数上下文中,允许执行类型转换。例如:

SELECT date_column
    FROM log_table
    WHERE date_column >= '2022-04-01'::DATE;
Copy

隐式类型转换(“强制转换”)

当函数(或运算符)需要的数据类型与实参(或操作数)不同但兼容时,就会发生强制转换。

  • 函数或存储过程的示例:

    • 下面的代码将列 my_integer_column 中的 INTEGER 值强制转换为 FLOAT,以便传递给需要 FLOAT 的函数 my_float_function()

      SELECT my_float_function(my_integer_column)
          FROM my_table;
      
      Copy
  • 运算符示例:

    • 下面的代码将 INTEGER 值 17 强制转换为 VARCHAR,以便使用 || 运算符连接这些值:

      SELECT 17 || '76';
      
      Copy

      此 SELECT 语句的结果是字符串 '1776'

    • 以下语句将列 my_integer_column 中的值 INTEGER 强制转换为 FLOAT,以便使用 < 比较运算符将该值与值 my_float_column 进行比较:

      SELECT ...
          FROM my_table
          WHERE my_integer_column < my_float_column;
      
      Copy

并非所有上下文(例如,并非所有运算符)都支持强制转换。

类型转换和优先级

在表达式内进行类型转换时,代码必须考虑转换运算符相对于表达式中其他运算符的优先级。

请参考以下示例:

SELECT height * width::VARCHAR || " square meters"
    FROM dimensions;
Copy

转换运算符的优先级高于算术运算符 * (乘法),因此该语句可解释为:

... height * (width::VARCHAR) ...
Copy

要转换表达式 height * width 的结果,请使用括号,如下所示:

SELECT (height * width)::VARCHAR || " square meters"
    FROM dimensions;
Copy

又例如,请注意以下语句:

SELECT -0.0::FLOAT::BOOLEAN;
Copy

您可能希望将其解释为:

SELECT (-0.0::FLOAT)::BOOLEAN;
Copy

因此返回 FALSE (0 = FALSE,1 = TRUE)。

但是,转换运算符的优先级高于一元减号(负号)运算符,因此该语句被解释为:

SELECT -(0.0::FLOAT::BOOLEAN);
Copy

因此会导致产生错误消息,因为一元减号不能应用于 BOOLEAN。

可转换的数据类型

下表显示了 Snowflake 中的有效数据类型转换。该表还显示了 Snowflake 可以自动执行的强制转换。

备注

在内部,CAST 函数和 :: 运算符会调用相应的转换函数。例如,如果将 NUMBER 转换为 BOOLEAN,则 Snowflake 将调用 TO_BOOLEAN 函数。当通过转换间接调用函数,以及直接调用函数时,各个转换函数的使用说明均适用。例如,如果执行 CAST(my_decimal_column as BOOLEAN),则应用使用 DECIMAL 值调用 TO_BOOLEAN 的规则。为方便起见,下表中的“备注”列包括了指向相关转换函数的链接。

有关 半结构化类型结构化类型 之间的转换的详细信息,请参阅 转换结构化类型和半结构化类型

源数据类型

目标数据类型

可转换

可强制转换

转换函数

备注

ARRAY

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

VECTOR

BINARY

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

BOOLEAN

NUMBER

TO_NUMBER

VARCHAR

TO_VARCHAR

例如,从 TRUE 到“true”。

VARIANT

TO_VARIANT

DATE

TIMESTAMP

TO_TIMESTAMP

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

FLOAT . (浮点数)

BOOLEAN

TO_BOOLEAN

例如,从 0.0 到 FALSE。

NUMBER[(p,s)]

TO_NUMBER

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

GEOGRAPHY

VARIANT

TO_VARIANT

GEOMETRY

VARIANT

TO_VARIANT

NUMBER[(p,s)] . (固定点数,包括 INTEGER)

BOOLEAN

TO_BOOLEAN

例如,从 0 到 FALSE。

FLOAT

TO_DOUBLE

TIMESTAMP

TO_TIMESTAMP

[1]

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

OBJECT

ARRAY

TO_ARRAY

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

TIME

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

TIMESTAMP

DATE

TO_DATE、DATE

TIME

TO_TIME、TIME

VARCHAR

TO_VARCHAR

VARIANT

TO_VARIANT

VARCHAR

BOOLEAN

TO_BOOLEAN

例如,从“false”到 FALSE。

DATE

TO_DATE、DATE

FLOAT

TO_DOUBLE

例如,从“12.34”到 12.34。

NUMBER[(p,s)]

TO_NUMBER

例如,从“12.34”到 12.34。

TIME

TO_TIME、TIME

TIMESTAMP

TO_TIMESTAMP

VARIANT

TO_VARIANT

VARIANT

ARRAY

TO_ARRAY

BOOLEAN

TO_BOOLEAN

例如,从包含“false”的 VARIANT 到 FALSE。

DATE

TO_DATE、DATE

FLOAT

TO_DOUBLE

GEOGRAPHY

TO_GEOGRAPHY

NUMBER[(p,s)]

TO_NUMBER

OBJECT

TO_OBJECT

TIME

TO_TIME、TIME

TIMESTAMP

TO_TIMESTAMP

VARCHAR

TO_VARCHAR

VECTOR

VARIANT 必须包含 FLOAT 或 INT 类型的 ARRAY。

VECTOR

ARRAY

TO_ARRAY

备注:

  • 对于列出的每个数据类型(例如 FLOAT),规则适用于该数据类型的所有别名(例如 FLOAT 的规则适用于 DOUBLE,也就是 FLOAT 的别名)。

使用说明

除非另有说明,否则以下规则适用于显式类型转换和隐式类型转换。

  • 转换不仅取决于数据类型,还取决于源的值。例如:

    • VARCHAR “123”可以转换为数值,但 VARCHAR“xyz”不能转换为数值。

    • 能否转换类型为 VARIANT 指定值取决于 VARIANT 内部 的数据类型。例如,如果 VARIANT 包含类型为 TIME 的值,则不能将 VARIANT 转换为 TIMESTAMP,因为不能将 TIME 转换为 TIMESTAMP。

  • 如果可能,请传入相同类型的实参。避免传入不同类型的实参。

  • 如果其中一个实参是数字,则函数会 强制转换 非数值字符串实参(例如 'a string')和不是类型 NUMBER(18,5) 常量的字符串实参。

    对于不是常量的数值字符串实参,如果 NUMBER(18,5) 不足以表示数值,则应将实参 转换 为可以表示该值的类型。

  • 对于某些数据类型对,转换可能会导致精度下降。例如:

    • 将 FLOAT 转换为 INTEGER 会舍入值。

    • 如果不能用浮点数精确表示定点数,则将值从定点数(例如 NUMBER(38, 0))转换为浮点数(例如,FLOAT)可能会导致舍入误差或截断。

    • 将 TIMESTAMP 转换为 DATE 将移除有关一天中时间的信息。

  • 尽管 Snowflake 会在某些可能发生精度损失的情况下转换值,但 Snowflake 不允许在可能发生精度损失的其他情况下执行转换。例如,当转换会出现以下情况时,Snowflake 不允许执行转换:

    • 截断 VARCHAR 值。例如,Snowflake 不会将 VARCHAR(10) 隐式或显式转换为 VARCHAR(5)。

    • 导致除最低有效位数以外的数字丢失。例如,以下语句会失败:

      select 12.3::FLOAT::NUMBER(3,2);
      
      Copy

    在此示例中,数字 12.3 在小数点之前有两位数字,但数据类型 NUMBER(3,2) 在小数点之前只有一位数字的空间。

  • 从精度较低的类型转换为精度较高的类型时,转换会使用默认值。例如,将 DATE 转换为 TIMESTAMP_NTZ 会导致小时、分钟、秒和小数秒值设置为 0。

  • 当 FLOAT 值被转换为 VARCHAR 时,尾零将省略。

    例如,以下语句会创建一个表并插入包含 VARCHAR、FLOAT 和 VARIANT 的行。VARIANT 使用包含用尾零表示浮点值的 JSON 构建。

    create or replace table tmp (
        varchar1 varchar, 
        float1 float, 
        variant1 variant
        );
    
    insert into tmp select '5.000', 5.000, parse_json('{"Loan Number": 5.000}');
    
    Copy

    以下 SELECT 语句将 VARIANT 列中的 FLOAT 列和 FLOAT 值显式转换为 VARCHAR。在每种情况下,VARCHAR 均不包含尾零:

    select varchar1, 
           float1::varchar,
           variant1:"Loan Number"::varchar from tmp;
    +----------+-----------------+---------------------------------+
    | VARCHAR1 | FLOAT1::VARCHAR | VARIANT1:"LOAN NUMBER"::VARCHAR |
    |----------+-----------------+---------------------------------|
    | 5.000    | 5               | 5                               |
    +----------+-----------------+---------------------------------+
    
    Copy
  • 某些操作可以返回不同的数据类型,具体取决于条件表达式。例如,以下 COALESCE 调用返回的数据类型略有不同,具体取决于输入值:

    select system$typeof(ifnull(12.3, 0)),
           system$typeof(ifnull(NULL, 0));
    
    +--------------------------------+--------------------------------+
    | SYSTEM$TYPEOF(IFNULL(12.3, 0)) | SYSTEM$TYPEOF(IFNULL(NULL, 0)) |
    +--------------------------------+--------------------------------+
    | NUMBER(3,1)[SB1]               | NUMBER(1,0)[SB1]               |
    +--------------------------------+--------------------------------+
    
    Copy

    如果表达式具有多个可能的数据类型,则 Snowflake 会根据实际结果选择数据类型。(有关计算中的精度和标度的更多信息,请参阅 算术运算的小数位数和精度。)如果查询生成多个结果(例如,多行结果),则 Snowflake 会选择能够保存每个单独结果的数据类型。

  • 某些应用程序(如 SnowSQL)和某些图形用户界面(例如 Classic Console)在显示数据时会应用自己的转换和格式设置规则。例如,SnowSQL 会将 BINARY 值显示为仅包含十六进制数字的字符串;该字符串是通过隐式调用转换函数生成的。因此,SnowSQL 显示的数据可能无法明确指示 Snowflake 强制转换了哪些数据。

语言: 中文