数据类型转换

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

本主题内容:

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

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

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

显式类型转换

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

  • CAST 函数。

  • The :: operator, called the cast operator.

  • The appropriate SQL function; for example, TO_DOUBLE.

例如,每个查询都将字符串值转换为 DATE 值:

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'

    • The following statement coerces the INTEGER value in column my_integer_column to FLOAT so that the value can be compared to the value my_float_column by using the < comparison operator:

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

Not all contexts --- for example, not all operators --- support coercion.

类型转换和优先级

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

请参考以下示例:

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

The cast operator has higher precedence than the arithmetic operator * (multiply), so the statement is interpreted as shown in the following example:

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

To cast the result of the expression height * width, use parentheses, as shown in the following example:

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

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

SELECT -0.0::FLOAT::BOOLEAN;
Copy

You might expect this to be interpreted as shown in the following example:

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

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

However, the cast operator has higher precedence than the unary minus (negation) operator, so the statement is interpreted as shown in the following example:

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

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

可转换的数据类型

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

备注

Internally, the CAST function and the :: operator call the appropriate conversion function. For example, if you cast a NUMBER to a BOOLEAN, Snowflake calls the TO_BOOLEAN function. The usage notes for each conversion function apply when the function is called indirectly by using a cast, and also when the function is called directly. For example, if you execute CAST(my_decimal_column AS BOOLEAN), the rules for calling TO_BOOLEAN with a DECIMAL value apply. For convenience, the table includes links to the relevant conversion functions.

For more information about conversions between semi-structured types and structured types, see 转换结构化类型和半结构化类型.

源数据类型

目标数据类型

可转换

可强制转换

转换函数

备注

ARRAY

VARCHAR

TO_VARCHAR

None.

VARIANT

TO_VARIANT

None.

VECTOR

使用 显式类型转换 进行转换。有关更多信息,请参阅 向量转换

BINARY

VARCHAR

TO_VARCHAR

None.

VARIANT

TO_VARIANT

None.

BOOLEAN

DECFLOAT

TO_DECFLOAT

For example, from FALSE to 0.

NUMBER

TO_NUMBER

None.

VARCHAR

TO_VARCHAR

例如,从 TRUE'true'

VARIANT

TO_VARIANT

None.

DATE

TIMESTAMP

TO_TIMESTAMP

None.

VARCHAR

TO_VARCHAR

None.

VARIANT

TO_VARIANT

None.

DECFLOAT . (decimal floating-point numbers)

BOOLEAN

TO_BOOLEAN

例如,从 0FALSE

FLOAT

TO_DOUBLE

None.

NUMBER[(p,s)]

TO_NUMBER

None.

VARCHAR

TO_VARCHAR

None.

FLOAT . (浮点数)

BOOLEAN

TO_BOOLEAN

例如,从 0.0FALSE

DECFLOAT

TO_DECFLOAT

None.

NUMBER[(p,s)]

TO_NUMBER

None.

VARCHAR

TO_VARCHAR

None.

VARIANT

TO_VARIANT

None.

GEOGRAPHY

VARIANT

TO_VARIANT

None.

GEOMETRY

VARIANT

TO_VARIANT

None.

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

BOOLEAN

TO_BOOLEAN

例如,从 0FALSE

DECFLOAT

TO_DECFLOAT

None.

FLOAT

TO_DOUBLE

None.

TIMESTAMP

TO_TIMESTAMP

[1]

VARCHAR

TO_VARCHAR

None.

VARIANT

TO_VARIANT

None.

OBJECT

ARRAY

TO_ARRAY

None.

VARCHAR

TO_VARCHAR

None.

VARIANT

TO_VARIANT

None.

TIME

VARCHAR

TO_VARCHAR

None.

VARIANT

TO_VARIANT

None.

TIMESTAMP

DATE

TO_DATE、DATE

None.

TIME

TO_TIME、TIME

None.

VARCHAR

TO_VARCHAR

None.

VARIANT

TO_VARIANT

None.

VARCHAR

BOOLEAN

TO_BOOLEAN

例如,从 'false'FALSE

DATE

TO_DATE、DATE

None.

DECFLOAT

TO_DECFLOAT

None.

FLOAT

TO_DOUBLE

例如,从 '12.34'12.34

NUMBER[(p,s)]

TO_NUMBER

例如,从 '12.34'12.34

TIME

TO_TIME、TIME

None.

TIMESTAMP

TO_TIMESTAMP

None.

VARIANT

TO_VARIANT

None.

VARIANT

ARRAY

TO_ARRAY

None.

BOOLEAN

TO_BOOLEAN

例如,从包含 'false' 的 VARIANT 到 FALSE

DATE

TO_DATE、DATE

None.

FLOAT

TO_DOUBLE

None.

GEOGRAPHY

TO_GEOGRAPHY

None.

NUMBER[(p,s)]

TO_NUMBER

None.

OBJECT

TO_OBJECT

None.

TIME

TO_TIME、TIME

None.

TIMESTAMP

TO_TIMESTAMP

None.

VARCHAR

TO_VARCHAR

None.

VECTOR

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

VECTOR

ARRAY

TO_ARRAY

None.

备注

For each listed data type --- for example, FLOAT --- the rules apply to all aliases for that data type. For example, the rules for FLOAT apply to DOUBLE, which is an alias for FLOAT.

使用说明

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

  • Conversion depends not only on the data type, but also the value, of the source; for example:

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

    • The ability to cast a specific value of type VARIANT depends on the type of the data inside the VARIANT. For example, if the VARIANT contains a value of type TIME, then you can't cast the VARIANT value to a TIMESTAMP value, because you can't cast a TIME value to a TIMESTAMP value.

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

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

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

  • For some pairs of data types, conversion can result in loss of precision; for example:

    • 将 FLOAT 值转换为 INTEGER 值将对该值进行舍入。

    • Converting a value from fixed-point numeric --- for example, NUMBER(38, 0) --- to floating point --- for example, FLOAT --- can result in rounding or truncation if the fixed-point number can't be precisely represented in a floating point number.

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

  • Although Snowflake converts values in some situations where loss of precision can occur, Snowflake doesn't allow conversion in other situations where a loss of precision would occur. For example, Snowflake doesn't allow conversion when conversion would cause the following situations to happen:

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

    • Result in the loss of digits other than the least significant digits. For example, the following loss of digits fails:

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

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

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

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

    For example, the following statements create a table and insert a row that contains a VARCHAR value, a FLOAT value, and a VARIANT value. The VARIANT value is constructed from JSON that contains a floating-point value represented with trailing zeros:

    CREATE OR REPLACE TABLE convert_test_zeros (
      varchar1 VARCHAR,
      float1 FLOAT,
      variant1 VARIANT);
    
    INSERT INTO convert_test_zeros 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 convert_test_zeros;
    
    Copy
    +----------+-----------------+---------------------------------+
    | VARCHAR1 | FLOAT1::VARCHAR | VARIANT1:"LOAN NUMBER"::VARCHAR |
    |----------+-----------------+---------------------------------|
    | 5.000    | 5               | 5                               |
    +----------+-----------------+---------------------------------+
    
  • Some operations can return different data types, depending on a conditional expression. For example, the following IFNULL calls return slightly different data types depending on the input values:

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

    If the expression has more than one possible data type, Snowflake chooses the data type based on the actual result. For more information about precision and scale in calculations, see 算术运算的小数位数和精度. If the query generates more than one result --- for example, multiple rows of results --- Snowflake chooses a data type that is capable of holding each of the individual results.

  • Some applications, such as SnowSQL, and some graphical user interfaces, such as the Classic Console, apply their own conversion and formatting rules when they display data. For example, SnowSQL displays BINARY values as a string that contains only hexadecimal digits; that string is generated by implicitly calling a conversion function. Therefore, the data that SnowSQL displays might not unambiguously indicate which data conversions that Snowflake coerced.

语言: 中文