数值数据类型

This topic describes the numeric data types supported in Snowflake, along with the supported formats for numeric constants and literals.

定点数的数据类型

Snowflake 支持以下定点数数据类型。

NUMBER

数字最多可达 38 位,精度和小数位数可选:

精度:

允许的总位数。

小数位数:

小数点右侧允许的位数。

By default, precision is 38, and scale is 0; that is, NUMBER(38, 0). Precision limits the range of values that can be inserted into or cast to columns of a given type. For example, the value 999 fits into NUMBER(38,0) but not into NUMBER(2,0).

Because precision is the total number of digits allowed, you can't load a value into a NUMBER column if the number of digits to the left of the decimal point exceeds the precision of the column minus its scale. For example, NUMBER(20, 2) allows 18 digits on the left side of the decimal point and two digits on the right side of the decimal point, for a total of 20 digits.

The maximum scale, which is the number of digits to the right of the decimal point, is 37. Numbers that have fewer than 38 significant digits, but whose least significant digit is past the 37th decimal place --- for example, 0.0000000000000000000000000000000000000012 (1.2e-39) --- can't be represented without losing some digits of precision.

备注

If data is converted to another data type with lower precision, and then converted back to the higher-precision data type, the data can lose precision. For example, precision is lost if you convert a NUMBER(38,37) value to a DOUBLE value --- which has a precision of approximately 15 decimal digits --- and then back to NUMBER.

Snowflake 还支持 FLOAT 数据类型,该类型允许的值范围更广,但精度较低。

DECIMAL、DEC、NUMERIC

与 NUMBER 同义。

INT、INTEGER、BIGINT、SMALLINT、TINYINT、BYTEINT

与 NUMBER 同义,但不能指定精度和小数位数(即始终默认为 NUMBER(38, 0))。因此,对于所有 INTEGER 数据类型,值范围都是从 -99999999999999999999999999999999999999 到 +99999999999999999999999999999999999999(含)的所有整数值。

The various names --- for example, TINYINT, BYTEINT, and so on ---are to simplify porting from other systems and to suggest the expected range of values for a column of the specified type.

精度和小数位数对存储大小的影响

Precision --- the total number of digits --- doesn't affect storage. The storage requirements for the same number in columns with different precisions, such as NUMBER(2,0) and NUMBER(38,0), are the same. For each micro-partition, Snowflake determines the minimum and maximum values for a given column and uses that information to determine the storage size for all values for that column in the partition. For example:

  • If a column contains only values between -128 and +127, each of the values consumes 1 byte (uncompressed).

  • If the largest value in the column is 10000000, each of the values consumes 4 bytes (uncompressed).

However, scale --- the number of digits following the decimal point --- affects storage. For example, the same value stored in a column of type NUMBER(10,5) consumes more space than NUMBER(5,0). Also, processing values with a larger scale might be slightly slower and consume more memory.

为了节省空间,Snowflake 会在将值写入存储之前对其进行压缩。压缩量取决于数据值和其他因素。

表中的定点数据类型示例

下面的语句创建了一个表,包含各种定点数据类型的列:

CREATE OR REPLACE TABLE test_fixed(
  num0 NUMBER,
  num10 NUMBER(10,1),
  dec20 DECIMAL(20,2),
  numeric30 NUMERIC(30,3),
  int1 INT,
  int2 INTEGER);

DESC TABLE test_fixed;
Copy
+-----------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name      | type         | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|-----------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| NUM0      | NUMBER(38,0) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| NUM10     | NUMBER(10,1) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| DEC20     | NUMBER(20,2) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| NUMERIC30 | NUMBER(30,3) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| INT1      | NUMBER(38,0) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| INT2      | NUMBER(38,0) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+-----------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+

浮点数的数据类型

Snowflake 支持以下浮点数数据类型。

FLOAT、FLOAT4、FLOAT8

名称 FLOAT、FLOAT4 和 FLOAT8 是为了与其他系统兼容;Snowflake 将这三类数值都视为 64 位浮点数。

精度

Snowflake 使用双精度(64 位)IEEE 754 浮点数。

Precision is approximately 15 digits. For example, for integers, the range is from -9007199254740991 to +9007199254740991 (-253 + 1 to +253 - 1). Floating-point values can range from approximately 10-308 to 10+308. Snowflake can represent more extreme values between approximately 10-324 and 10-308 with less precision. For more details, see the Wikipedia article on double-precision numbers (link removed).

Snowflake 支持定点数据类型 NUMBER,尽管指数范围较小,但允许更高的精度。

特殊值

Snowflake 支持以下 FLOAT 类型的特殊值:

  • :code:`'NaN'`(不是数字)

  • :code:`'inf'`(无穷大)

  • :code:`'-inf'`(负无穷大)

符号 'NaN''inf''-inf' 必须放在单引号内,并且不区分大小写。

'NaN' 的比较语义与 IEEE 754 标准在以下方面有所不同:

条件

Snowflake

IEEE 754

注释

'NaN' = 'NaN'

TRUE

FALSE

在 Snowflake 中,'NaN' 值都是相等的。

'NaN' > X . where X is any FLOAT value, including . infinity, other than NaN itself.

TRUE

FALSE

在 Snowflake 中,'NaN' 大于 . 任何其他 FLOAT 值,. 包括无穷大。

舍入误差

浮点运算在最低有效位数中可能会有微小的舍入误差。舍入误差可能发生在任何类型的浮点处理中,包括三角函数、统计函数和地理空间函数。

The following list shows considerations for rounding errors:

  • 每次执行查询时,误差都可能有所不同。

  • 当操作数具有不同的精度或小数位数时,误差可能会更大。

  • Errors can accumulate, especially when aggregate functions ---for example, SUM or AVG --- process large numbers of rows. Casting to a fixed-point data type before aggregating can reduce or eliminate these errors.

  • Rounding errors can occur not only when working with SQL, but also when working with other code --- for example, Java, JavaScript, or Python --- that runs inside Snowflake --- for example, in UDFs and stored procedures.

  • 在比较两个浮点数时,Snowflake 建议比较近似相等性而不是完全相等性。

通过使用精确的 DECFLOAT 数据类型,可能会避免这类近似误差。

DOUBLE、DOUBLE PRECISION、REAL

与 FLOAT 同义。

表中的浮点数据类型示例

下面的语句创建了一个表,包含各种浮点数据类型的列:

CREATE OR REPLACE TABLE test_float(
  double1 DOUBLE,
  float1 FLOAT,
  dp1 DOUBLE PRECISION,
  real1 REAL);

DESC TABLE test_float;
Copy
+---------+-------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
| name    | type  | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|---------+-------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
| DOUBLE1 | FLOAT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| FLOAT1  | FLOAT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| DP1     | FLOAT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| REAL1   | FLOAT | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+---------+-------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+

备注

The DESC TABLE command's type column displays the data type FLOAT not only for FLOAT, but also for synonyms of FLOAT; for example, DOUBLE, DOUBLE PRECISION, and REAL.

DECFLOAT

十进制浮点数 (DECFLOAT) 数据类型精确存储数字,精度高达 38 位有效数字,并使用以 10 为底的动态指数来表示非常大或非常小的值。指数范围为 -16383 到 16384,允许值大约介于 -10^(16384) 到 10^(16384) 之间。DECFLOAT 数据类型支持变量小数位数,因此小数位数会根据存储的特定值而变化。与 FLOAT 数据类型以近似值表示数值不同,DECFLOAT 数据类型会在指定的精度范围内表示精确值。

DECFLOAT 数据类型不支持以下 FLOAT 数据类型支持的 特殊值'NaN'`(非数字),:code:'inf'(无穷大),以及 :code:'-inf'`(负无穷大)。

DECFLOAT 数据类型用例

当您需要精确的小数结果和同一列中的宽、变量小数位数时,使用 DECFLOAT 数据类型。

DECFLOAT 数据类型适用于以下一般用例:

  • 您正在引入数据,传入数值的范围未知或高度可变。

  • 您需要精确的数值;例如,分类账、税收或合规性。

  • 您正在从依赖 IEEE 754 十进制表示或 128 位十进制数的系统进行迁移。这些迁移可能会受到其他 Snowflake 数据类型的精度或范围限制的阻碍。

  • 您想避免 Number out of representable range 对高精度数值进行求和、乘法或除法运算时出现的错误。

例如,您可以使用以下特定用例的 DECFLOAT 数据类型:

  • 您正在从 Oracle DECIMAL 或 DB2 DECFLOAT 列引入异构扩展的数据。

  • 您正在执行的财务建模涉及到难以预测的结果规模的计算。

  • 您正在运行从纳单位到天文单位的科学测量。

您可以继续使用固定小数位数列的 NUMBER 数据类型或用于高吞吐量分析的 FLOAT 数据类型,其中不精确的结果是可以接受的。

使用 DECFLOAT 数据类型说明

  • 如果运算产生的结果超过 38 位,则 DECFLOAT 值四舍五入到 38 位精度,最低有效数字根据当前舍入模式四舍五入。对于 DECFLOAT 值,Snowflake 使用 半向上舍入模式 (link removed)。

  • 当您指定 DECFLOAT 值或转换为 DECFLOAT 值时,避免在 SQL 中使用数值字面量。如果在 SQL 中使用数值字面量,值解释为 NUMBER 或 FLOAT 值,然后再转换为 DECFLOAT 值,这可能会导致范围错误或准确性损失。相反,使用任一字符串字面量,例如 SELECT '<value>'::DECFLOAT,或 DECFLOAT 字面量,例如 SELECTDECFLOAT '<value>'

  • 当混合操作 DECFLOAT 值和其他数值类型的值时,强制转换更喜欢 DECFLOAT 值。例如,当您添加以下 NUMBER 类型和 DECFLOAT 类型值时,结果是 DECFLOAT 值。

  • 使用 DECFLOAT 类型可能会导致存储消耗增加。

支持 DECFLOAT 数据类型的驱动程序和驱动程序版本

以下 Snowflake 驱动程序和驱动程序版本支持 DECFLOAT 数据类型。可能需要将驱动程序更新到支持 DECFLOAT 的版本。

驱动程序

支持的最低版本

备注

Snowflake Connector for Python

3.14.1

Pandas DataFrames 不支持 DECFLOAT 类型。

ODBC

3.12.0

无。

JDBC

3.27.0

无。

Go Snowflake Driver

1.17.0

无。

不受支持的驱动程序会将 DECFLOAT 值处理为 TEXT 值。对于某些驱动程序,必须设置驱动程序参数以将 DECFLOAT 类型映射为语言的原生类型。有关更多信息,请参阅 驱动程序

DECFLOAT 数据类型的限制

以下限制适用于 DECFLOAT 数据:

  • DECFLOAT 值不能存储在 VARIANT、OBJECT 或 ARRAY 值。要将 DECFLOAT 值转换为 VARIANT 值,您可以先将其转换为 VARCHAR 值,然后将其转换为 VARIANT 值。

  • 以下类型的表不支持 DECFLOAT 值:

    • 外部格式的表,例如 Iceberg

    • 混合表

  • DECFLOAT 数据类型在 Snowflake Scripting 的存储过程中不受支持。但是,在 Snowflake Scripting 用户定义的函数 (UDFs) 中受支持。

  • DECFLOAT 在存储过程或使用非 SQL 语言(例如 Python 或 Java)编写的 UDFs 中不受支持。

  • Snowpark 不支持 DECFLOAT 数据类型。

  • Snowsight 对 DECFLOAT 数据类型的支持有限。

  • 以下功能不支持 DECFLOAT 数据类型:

  • NUMBER 和 FLOAT 类型可能提供比 DECFLOAT 类型更好的性能。

Examples for the DECFLOAT data type

以下示例使用 DECFLOAT 数据类型:

显示 DECFLOAT 和 FLOAT 之间的差异

以下示例显示了 DECFLOAT 和 FLOAT 数据类型之间的差异:

  1. 创建一个表,其中包含 DECFLOAT 列和 FLOAT 列,然后将两种类型的相同值插入到表中:

    CREATE OR REPLACE TABLE decfloat_sample (
      id INT,
      decfloat_val DECFLOAT,
      float_val FLOAT);
    
    INSERT INTO decfloat_sample VALUES
      (
        1,
        DECFLOAT '123e7000',
        FLOAT '123e7000'
      ),
      (
        2,
        12345678901234567890123456789::DECFLOAT,
        12345678901234567890123456789::FLOAT
      ),
      (
        3,
        '-4.2e-5432'::DECFLOAT,
        '-4.2e-5432'::FLOAT
      ),
      (
        4,
        '1.00000000000000000000000000000000000014'::DECFLOAT,
        '1.00000000000000000000000000000000000014'::FLOAT
      ),
      (
        5,
        '1.00000000000000000000000000000000000015'::DECFLOAT,
        '1.00000000000000000000000000000000000015'::FLOAT
      );
    
    Copy

    该语句通过以下方式插入 DECFLOAT 值:

    • 第一个值是通过使用 DECFLOAT 字面量插入。

    • 第二个值通过将 INTEGER 值转换为 DECFLOAT 值插入。

    • 第三个、第四个和第五个值通过将 VARCHAR 值转换为 DECFLOAT 值插入。

  2. 要显示类型,请使用 DESC TABLE 命令来描述该表。

    任一列的表定义中均未指定精度,但输出显示 DECFLOAT 数据类型最多支持 38 位有效数字的精度:

    DESC TABLE decfloat_sample;
    
    Copy
    +--------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
    | name         | type         | kind   | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
    |--------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------|
    | ID           | NUMBER(38,0) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
    | DECFLOAT_VAL | DECFLOAT(38) | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
    | FLOAT_VAL    | FLOAT        | COLUMN | Y     | NULL    | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
    +--------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+----------------+
    
  3. 要显示值的差异,请使用 SELECT 语句查询该表:

    SELECT * FROM decfloat_sample;
    
    Copy
    +----+-----------------------------------------+------------------------+
    | ID | DECFLOAT_VAL                            |              FLOAT_VAL |
    |----+-----------------------------------------+------------------------|
    |  1 | 1.23e7002                               | inf                    |
    |  2 | 12345678901234567890123456789           |   1.23456789012346e+28 |
    |  3 | -4.2e-5432                              |  -0                    |
    |  4 | 1.0000000000000000000000000000000000001 |   1                    |
    |  5 | 1.0000000000000000000000000000000000002 |   1                    |
    +----+-----------------------------------------+------------------------+
    

    输出显示以下差异:

    • 第一行显示 DECFLOAT 类型支持的值范围比 FLOAT 类型更大。DECFLOAT 值非常大 (1.23e7002)。FLOAT 值为 inf,这意味着该值大于 FLOAT 类型所能表示的任何数值。

    • 第二行显示 DECFLOAT 类型完全保留指定的值。FLOAT 值是以科学记数法存储的近似值。

    • 第三行显示 DECFLOAT 类型支持非常小的值 (-4.2e-5432)。FLOAT 值近似为 -0

    • 第四行和第五行显示 DECFLOAT 类型支持高达 38 位的精度,并对超出限制的值使用舍入规则。FLOAT 值在两行中近似为 1

在聚合函数中使用 DECFLOAT 值

以下示例演示了在聚合函数中使用 DECFLOAT 值:

  1. 创建表,然后将 DECFLOAT 值插入表中:

    CREATE OR REPLACE TABLE decfloat_agg_sample (decfloat_val DECFLOAT);
    
    INSERT INTO decfloat_agg_sample VALUES
      (DECFLOAT '1e1000'),
      (DECFLOAT '-2.47e999'),
      (DECFLOAT '22e-75');
    
    Copy
  2. 使用一些聚合函数查询表:

    SELECT SUM(decfloat_val),
           AVG(decfloat_val),
           MAX(decfloat_val),
           MIN(decfloat_val)
      FROM decfloat_agg_sample;
    
    Copy
    +-------------------+-------------------+-------------------+-------------------+
    | SUM(DECFLOAT_VAL) | AVG(DECFLOAT_VAL) | MAX(DECFLOAT_VAL) | MIN(DECFLOAT_VAL) |
    |-------------------+-------------------+-------------------+-------------------|
    | 7.53e999          | 2.51e999          | 1e1000            | -2.47e999         |
    +-------------------+-------------------+-------------------+-------------------+
    

数值常量

The term constants --- also known as literals --- refers to fixed data values. The following formats are supported for numeric constants:

[+-][digits][.digits][e[+-]digits]

其中:

  • +- 表示正值或负值。默认为正值。

  • digits 是 0 到 9 范围内的一个或多个数字。

  • e (或 E)表示科学记数法中的指数。指数标记后必须至少有一位数字(如果存在)。

以下数字都是受支持的数值常量的示例:

15
+1.34
0.2
15e-03
1.234E2
1.234E+2
-1
语言: 中文