算术运算符

算术运算符用于从一个或多个输入表达式生成数值输出。

输入表达式必须为数值(定点或浮点),但以下情况除外:

  • 一元运算符 + 可以采用数字字符串,但这会导致字符串隐式转换为其相应的数值。

  • 二进制运算符 - 可应用于 DATE 表达式。

本主题内容:

算术运算符列表

运算符

语法

描述

+ (一元)

+a

返回 a,这将导致 a 隐式转换为数值。如果 a 是字符串,但无法将字符串转换为数值,则返回错误。

+

a + b

添加两个数值表达式(ab)。

- (一元)

-a

否定输入数值表达式。

-

a - b

从一个数值表达式 (a) 中减去另一个数值表达式 (b)。

-

a - b

从一个日期表达式 (a) 中减去另一个日期表达式 (b)。结果是整数天数。减法是唯一允许对 DATE 表达式进行算术运算的运算。

*

a * b

将两个数值表达式(ab)相乘。

/

a / b

将一个数值表达式 (a) 除以另一个数值表达式 (b)。对于除以 0 或 NULL 时返回 0 的函数,请参阅 DIV0DIV0NULL

%

a % b

计算每个 b 的数值表达式 a 的模。另请参阅 MOD

算术运算的小数位数和精度

算术运算输出的 小数位数精度 取决于输入的小数位数和精度。

本部分介绍 Snowflake 用于在各种算术运算(乘法、除法等)生成的数值输出中保留小数位数和精度的计算。本部分使用以下说明:

前导数字:

数值中小数点左侧的位数 (L)。

小数位数:

数值中小数点右侧的位数 (S)。

精度:

数值中的位总数 (P),以其前导数字和小数位数之和来计算(即 P = L + S)。请注意,Snowflake 中的精度始终限制为 38。

另外:

  • 定点数据类型(NUMBER、DECIMAL 等)使用精度和小数位数。例如,对于 DECIMAL (8、2)数据类型,精度为 8,小数位数为 2,前导数字为 6。

  • 浮点数据类型(FLOAT、DOUBLE、REAL 等)使用 8 字节双精度。

对于输出,请注意这些是最大位数;任何给定输出的实际位数可能更少。

乘法

执行乘法时:

  • 输出中的前导位数是两个输入中前导位数的总和。

  • Snowflake 通过在两个输入的小数位数中添加位数(最大阈值为 12 位)来最小化潜在的溢出(由于链式乘法),除非任一输入的小数位数大于 12,在这种情况下,较大的输入小数位数用作输出小数位数。

换言之,假设使用两个输入(L1.S1L2.S2)进行乘法运算,输出中的最大位数计算如下:

前导数字:

L = L1 + L2

小数位数:

S = min(S1 + S2, max(S1, S2, 12))

精度:

P = L + S

备注

Snowflake 对数值执行整型乘法运算,因此中间结果可能会导致一些溢出;但是,最终输出不会溢出。

示例

select 10.01 n1, 1.1 n2, n1 * n2;

+-------+-----+---------+
|    N1 |  N2 | N1 * N2 |
|-------+-----+---------|
| 10.01 | 1.1 |  11.011 |
+-------+-----+---------+

select 10.001 n1, .001 n2, n1 * n2;

+--------+-------+----------+
|     I1 |    I2 |  I1 * I2 |
|--------+-------+----------|
| 10.001 | 0.001 | 0.010001 |
+--------+-------+----------+

select .1 n1, .0000000000001 n2, n1 * n2;

+-----+-----------------+-----------------+
|  N1 |              N2 |         N1 * N2 |
|-----+-----------------+-----------------|
| 0.1 | 0.0000000000001 | 0.0000000000000 |
+-----+-----------------+-----------------+
Copy

除法

执行除法时:

  • 输出的前导数字是分子的前导数字和分母的小数位数的总和。

  • Snowflake 通过向分子的小数位数添加 6 位数字(最大阈值为 12 位)来最大程度地减少输出中的潜在溢出(由于链式除法)和小数位数损失,除非分子的小数位数大于 12,在这种情况下,分子的小数位数用作输出的小数位数。

换言之,假设使用分子 L1.S1 和分母 L2.S2 进行除法运算,输出中的最大位数计算如下:

前导数字:

L = L1 + S2

小数位数:

S = max(S1, min(S1 + 6, 12))

精度:

P = L + S

如果除法运算的结果超过输出小数位数,则 Snowflake 将对输出进行舍入(而不是截断输出)。

备注

与乘法类似,中间除法结果可能会导致一些溢出;但是,最终输出不会溢出。

示例

select 2 n1, 7 n2, n1 / n2;

+----+----+----------+
| N1 | N2 |  N1 / N2 |
|----+----+----------|
|  2 |  7 | 0.285714 |
+----+----+----------+

select 10.1 n1, 2.1 n2, n1 / n2;

+------+-----+-----------+
|   N1 |  N2 |   N1 / N2 |
|------+-----+-----------|
| 10.1 | 2.1 | 4.8095238 |
+------+-----+-----------+

select 10.001 n1, .001 n2, n1 / n2;

+--------+-------+-----------------+
|     N1 |    N2 |         N1 / N2 |
|--------+-------+-----------------|
| 10.001 | 0.001 | 10001.000000000 |
+--------+-------+-----------------+

select .1 n1, .0000000000001 n2, n1 / n2;

+-----+-----------------+-----------------------+
|  N1 |              N2 |               N1 / N2 |
|-----+-----------------+-----------------------|
| 0.1 | 0.0000000000001 | 1000000000000.0000000 |
+-----+-----------------+-----------------------+
Copy

加法和减法

对于加法或减法:

  • 输出的前导位数是输入的最大前导位数加上 1(以保留进位值)。

  • 输出的小数位数是输入的最大小数位数。

换言之,假设一个加法或减法运算有两个输入(L1.S1L2.S2),输出中的最大位数计算如下:

前导数字:

L = max(L1, L2) + 1

小数位数:

S = max(S1, S2)

精度:

P = L + S

其他 N 元运算

对于具有多个数字输入的所有其他算术运算,例如模(a % bMOD):

  • 输出的前导位数是输入的最大前导位数。

  • 输出的小数位数是输入的最大小数位数。

换言之,假设对输入 L1.S1L2.S2 等进行 N 元运算,则输出中的最大位数计算如下:

前导数字:

L = max(L1, L2, ...)

小数位数:

S = max(S1, S2, ...)

精度:

P = L + S

一元运算

一元算术运算的输出精度和小数位数与输入精度和小数位数相同,但允许显式指定输出小数位数的 ROUND 除外。

按位运算

支持的按位算术运算列表可在 条件表达式函数 中找到。

注意:

  • 对于数值,按位运算仅对输入中的前导数字进行运算。输出的小数位数始终为零。

  • 对于二进制按位运算,输出的前导位数与输入中的最大前导位数相同。

语言: 中文