跳到主要内容
跳到主要内容

算术函数

概述

算术函数适用于任意两个 UInt8UInt16UInt32UInt64Int8Int16Int32Int64Float32Float64 类型的操作数。

在执行操作之前,两个操作数都会被转换为结果类型。结果类型的确定如下(除非在下面的函数文档中另有说明):

  • 如果两个操作数的位数都不超过 32 位,则结果类型的大小将是两个操作数中较大者的下一个较大类型的大小(整数大小提升)。例如,UInt8 + UInt16 = UInt32Float32 * Float32 = Float64
  • 如果其中一个操作数的位数为 64 或更多,则结果类型的大小将与较大操作数的大小相同。例如,UInt32 + UInt128 = UInt128Float32 * Float64 = Float64
  • 如果其中一个操作数是有符号的,则结果类型也将是有符号的,否则将是无符号的。例如,UInt32 * Int32 = Int64

这些规则确保结果类型将是可以表示所有可能结果的最小类型。虽然这在值范围边界周围引入了溢出的风险,但它确保计算是使用最大原生整数宽度(64 位)快速执行的。这种行为还确保与许多其他提供 64 位整数(BIGINT)作为最大整数类型的数据库兼容。

示例:

SELECT toTypeName(0), toTypeName(0 + 0), toTypeName(0 + 0 + 0), toTypeName(0 + 0 + 0 + 0)
┌─toTypeName(0)─┬─toTypeName(plus(0, 0))─┬─toTypeName(plus(plus(0, 0), 0))─┬─toTypeName(plus(plus(plus(0, 0), 0), 0))─┐
│ UInt8         │ UInt16                 │ UInt32                          │ UInt64                                   │
└───────────────┴────────────────────────┴─────────────────────────────────┴──────────────────────────────────────────┘

溢出与 C++ 中的处理方法相同。

abs

引入于:v1.1

计算 x 的绝对值。如果 x 是无符号类型则无效。如果 x 是有符号类型,则返回无符号数。

语法

abs(x)

参数

  • x — 计算绝对值的值

返回值

x 的绝对值

示例

使用示例

SELECT abs(-0.5)
0.5

byteSwap

引入于:v23.10

反转整数的字节,即更改其 字节序

如下示例可以这样处理:

  1. 将十进制整数字转换为其等效的大端格式的十六进制格式,即 3351772109 -> C7 C7 FB CD(4 字节)
  2. 反转字节,即 C7 C7 FB CD -> CD FB C7 C7
  3. 将结果假设为大端格式转换回整数,即 CD FB C7 C7 -> 3455829959 该函数的一个用例是反转 IPv4:
┌─toIPv4(byteSwap(toUInt32(toIPv4('205.251.199.199'))))─┐
│ 199.199.251.205                                       │
└───────────────────────────────────────────────────────┘

语法

byteSwap(x)

参数

返回值

返回字节反转后的 x(U)Int*

示例

使用示例

SELECT byteSwap(3351772109)
3455829959

8位

SELECT byteSwap(54)
54

16位

SELECT byteSwap(4135)
10000

32位

SELECT byteSwap(3351772109)
3455829959

64位

SELECT byteSwap(123294967295)
18439412204227788800

divide

引入于:v1.1

计算两个值 ab 的商。结果类型始终为 Float64。 整数除法由 intDiv 函数提供。

备注

除以 0 会返回 inf-infnan

语法

divide(x, y)

参数

  • x — 被除数 - y — 除数

返回值

xy 的商

示例

除以两个数字

SELECT divide(25,5) AS quotient, toTypeName(quotient)
5 Float64

除以零

SELECT divide(25,0)
inf

divideDecimal

引入于:v22.12

对两个十进制数进行除法运算。结果值的类型将是 Decimal256。 结果规模可以通过 result_scale 参数显式指定(范围为 [0, 76] 的常量整数)。如果没有指定,结果规模为给定参数的最大规模。

备注

这些函数的工作速度显著慢于常规的 divide。 如果您真的不需要受控精度和/或需要快速计算,考虑使用 divide

语法

divideDecimal(x, y[, result_scale])

参数

  • x — 第一个值:Decimal。 - y — 第二个值:Decimal。 - result_scale — 结果的规模。类型为 Int/UInt

返回值

具有给定规模的除法结果。Decimal256

示例

示例 1

divideDecimal(toDecimal256(-12, 0), toDecimal32(2.1, 1), 10)
┌─divideDecimal(toDecimal256(-12, 0), toDecimal32(2.1, 1), 10)─┐
│                                                -5.7142857142 │
└──────────────────────────────────────────────────────────────┘

示例 2

SELECT toDecimal64(-12, 1) / toDecimal32(2.1, 1);
SELECT toDecimal64(-12, 1) as a, toDecimal32(2.1, 1) as b, divideDecimal(a, b, 1), divideDecimal(a, b, 5);
┌─divide(toDecimal64(-12, 1), toDecimal32(2.1, 1))─┐
│                                             -5.7 │
└──────────────────────────────────────────────────┘
┌───a─┬───b─┬─divideDecimal(toDecimal64(-12, 1), toDecimal32(2.1, 1), 1)─┬─divideDecimal(toDecimal64(-12, 1), toDecimal32(2.1, 1), 5)─┐
│ -12 │ 2.1 │                                                       -5.7 │                                                   -5.71428 │
└─────┴─────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘

divideOrNull

引入于:v25.5

divide 相同,但在除以零时返回 NULL。

语法

divideOrNull(x, y)

参数

  • x — 被除数 - y — 除数

返回值

xy 的商,或者 NULL。

示例

除以零

SELECT divideOrNull(25, 0)
\N

gcd

引入于:v1.1

返回两个值 ab 的最大公约数。

除以零或将最小负数除以 -1 会引发异常。

语法

gcd(x, y)

参数

  • x — 第一个整数 - y — 第二个整数

返回值

xy 的最大公约数。

示例

使用示例

SELECT gcd(12, 18)
6

ifNotFinite

引入于:v20.3

检查浮点值是否为有限值。

您可以通过使用 三元操作符 获得类似的结果:isFinite(x) ? x : y

语法

ifNotFinite(x,y)

参数

  • x — 要检查是否为无限大的值。Float*
  • y — 后备值。Float*

返回值

  • 如果 x 是有限的,则返回 x
  • 如果 x 不是有限的,则返回 y

示例

使用示例

SELECT 1/0 AS infimum, ifNotFinite(infimum,42)
inf  42

intDiv

引入于:v1.1

对两个值 x 除以 y 进行整数除法。换句话说,它计算向下取整到下一个最小整数的商。

结果的宽度与被除数(第一个参数)相同。

除以零、商不适合被除数范围或将最小负数除以 -1 会引发异常。

语法

intDiv(x, y)

参数

  • x — 左操作数。 - y — 右操作数。

返回值

xy 的整数除法结果

示例

两个浮点数的整数除法

SELECT intDiv(toFloat64(1), 0.001) AS res, toTypeName(res)
┌──res─┬─toTypeName(intDiv(toFloat64(1), 0.001))─┐
│ 1000 │ Int64                                   │
└──────┴─────────────────────────────────────────┘

商不适合被除数的范围

SELECT
intDiv(1, 0.001) AS res,
toTypeName(res)
Received exception from server (version 23.2.1):
Code: 153. DB::Exception: Received from localhost:9000. DB::Exception:
Cannot perform integer division, because it will produce infinite or too
large number: While processing intDiv(1, 0.001) AS res, toTypeName(res).
(ILLEGAL_DIVISION)

intDivOrNull

引入于:v25.5

intDiv 相同,但在除以零或将最小负数除以 -1 时返回 NULL。

语法

intDivOrNull(x, y)

参数

返回值

xy 的整数除法结果,或 NULL。

示例

整数除法除以零

SELECT intDivOrNull(1, 0)
\N

将最小负数除以 -1

SELECT intDivOrNull(-9223372036854775808, -1)
\N

intDivOrZero

引入于:v1.1

intDiv 相同,但在除以零或将最小负数除以 -1 时返回零。

语法

intDivOrZero(a, b)

参数

返回值

ab 的整数除法结果,或零。

示例

整数除法除以零

SELECT intDivOrZero(1, 0)
0

将最小负数除以 -1

SELECT intDivOrZero(0.05, -1)
0

isFinite

引入于:v1.1

如果 Float32 或 Float64 参数不是无限大且不是 NaN,则返回 1,否则此函数返回 0

语法

isFinite(x)

参数

  • x — 要检查是否为有限值的数字。Float*

返回值

如果 x 不是无限的且不是 NaN,则返回 1,否则返回 0

示例

测试一个数字是否有限

SELECT isFinite(inf)
0

isInfinite

引入于:v1.1

如果 Float32 或 Float64 参数是无限的,则返回 1,否则此函数返回 0。 请注意,对于 NaN 返回 0

语法

isInfinite(x)

参数

  • x — 要检查是否为无限大的数字。Float*

返回值

如果 x 是无限的,则返回 1,否则返回 0(包括对于 NaN)。

示例

测试一个数字是否是无限的

SELECT isInfinite(inf), isInfinite(NaN), isInfinite(10))
1 0 0

isNaN

引入于:v1.1

如果 Float32 和 Float64 参数是 NaN,则返回 1,否则返回 0

语法

isNaN(x)

参数

  • x — 要评估其是否为 NaN 的参数。Float*

返回值

如果是 NaN,则返回 1,否则返回 0

示例

使用示例

SELECT isNaN(NaN)
1

lcm

引入于:v1.1

返回两个值 xy 的最小公倍数。

除以零或将最小负数除以 -1 会引发异常。

语法

lcm(x, y)

参数

返回值

返回 xy 的最小公倍数。(U)Int*

示例

使用示例

SELECT lcm(6, 8)
24

max2

引入于:v21.11

返回两个数值 xy 中较大的一个。

语法

max2(x, y)

参数

返回值

返回 xy 中较大的值。Float64

示例

使用示例

SELECT max2(-1, 2)
2

min2

引入于:v21.11

返回两个数值 xy 中较小的一个。

语法

min2(x, y)

参数

返回值

返回 xy 中较小的值。Float64

示例

使用示例

SELECT min2(-1, 2)
-1

minus

引入于:v1.1

计算两个值 ab 的差。结果始终为有符号。类似于加法,可以从日期或带时间的日期中减去整数。 此外,也支持带时间的日期之间的减法,从而得出它们之间的时间差。

语法

minus(x, y)

参数

  • x — 被减数。 - y — 减数。

返回值

x 减去 y

示例

减去两个数字

SELECT minus(10, 5)
5

从日期中减去一个整数

SELECT minus(toDate('2025-01-01'),5)
2024-12-27

modulo

引入于:v1.1

计算两个值 a 除以 b 的余数。

如果两个输入都是整数,结果类型为整数。如果其中一个输入是浮点数,结果类型为 Float64。

余数是按 C++ 中的方式计算的。负数使用截断除法。

除以零或将最小负数除以 -1 会引发异常。

语法

modulo(a, b)

参数

  • a — 被除数 - b — 除数(模数)

返回值

a % b 的余数

示例

使用示例

SELECT modulo(5, 2)
1

moduloOrNull

引入于:v25.5

计算 a 除以 b 的余数。类似于 modulo 函数,不同之处在于 moduloOrNull 如果右侧参数为 0 则会返回 NULL。

语法

moduloOrNull(x, y)

参数

返回值

返回 xy 除的余数,或当除数为零时返回 null。

示例

moduloOrNull 除以零

SELECT moduloOrNull(5, 0)
\N

moduloOrZero

引入于:v20.3

modulo 相似,但在除数为零时返回零,而不是 modulo 函数中的异常。

语法

moduloOrZero(a, b)

参数

返回值

返回 a % b 的余数,或当除数为 0 时返回 0

示例

使用示例

SELECT moduloOrZero(5, 0)
0

multiply

引入于:v1.1

计算两个值 xy 的乘积。

语法

multiply(x, y)

参数

返回值

返回 xy 的乘积

示例

乘以两个数字

SELECT multiply(5,5)
25

multiplyDecimal

引入于:v22.12

对两个十进制数进行乘法运算。结果值的类型将是 Decimal256。 结果规模可以通过 result_scale 参数显式指定(范围为 [0, 76] 的常量整数)。如果没有指定,结果规模为给定参数的最大规模。

备注

这些函数的工作速度显著慢于常规的 multiply。 如果您真的不需要受控精度和/或需要快速计算,考虑使用 multiply

语法

multiplyDecimal(a, b[, result_scale])

参数

返回值

具有给定规模的乘法结果。类型: Decimal256

示例

使用示例

SELECT multiplyDecimal(toDecimal256(-12, 0), toDecimal32(-2.1, 1), 1)
25.2

与常规乘法的区别

SELECT multiplyDecimal(toDecimal256(-12, 0), toDecimal32(-2.1, 1), 1)
┌─multiply(toDecimal64(-12.647, 3), toDecimal32(2.1239, 4))─┐
│                                               -26.8609633 │
└───────────────────────────────────────────────────────────┘
┌─multiplyDecimal(toDecimal64(-12.647, 3), toDecimal32(2.1239, 4))─┐
│                                                         -26.8609 │
└──────────────────────────────────────────────────────────────────┘

十进制溢出

SELECT
    toDecimal64(-12.647987876, 9) AS a,
    toDecimal64(123.967645643, 9) AS b,
    multiplyDecimal(a, b);
SELECT
    toDecimal64(-12.647987876, 9) AS a,
    toDecimal64(123.967645643, 9) AS b,
    a * b;
┌─────────────a─┬─────────────b─┬─multiplyDecimal(toDecimal64(-12.647987876, 9), toDecimal64(123.967645643, 9))─┐
│ -12.647987876 │ 123.967645643 │                                                               -1567.941279108 │
└───────────────┴───────────────┴───────────────────────────────────────────────────────────────────────────────┘
Received exception from server (version 22.11.1):
Code: 407. DB::Exception: Received from localhost:9000. DB::Exception: Decimal math overflow:
While processing toDecimal64(-12.647987876, 9) AS a, toDecimal64(123.967645643, 9) AS b, a * b. (DECIMAL_OVERFLOW)

negate

引入于:v1.1

对参数 x 取反。结果始终为有符号。

语法

negate(x)

参数

  • x — 要取反的值。

返回值

返回 -x

示例

使用示例

SELECT negate(10)
-10

plus

引入于:v1.1

计算两个值 xy 的和。别名:x + y(操作符)。 可以将整数和日期或带时间的日期相加。前一种操作增加日期中的天数,后一种操作增加带时间的日期中的秒数。

语法

plus(x, y)

参数

  • x — 左操作数。 - y — 右操作数。

返回值

返回 xy 的和

示例

加上两个数字

SELECT plus(5,5)
10

加上一个整数和一个日期

SELECT plus(toDate('2025-01-01'),5)
2025-01-06

positiveModulo

引入于:v22.11

计算 x 除以 y 的余数。与 modulo 函数类似,不同之处在于 positiveModulo 始终返回非负数。

语法

positiveModulo(x, y)

参数

返回值

返回x 与最大不大于 x 的可被 y 整除的整数之间的差。

示例

使用示例

SELECT positiveModulo(-1, 10)
9

positiveModuloOrNull

引入于:v25.5

计算 a 除以 b 的余数。与 positiveModulo 函数类似,不同之处在于 positiveModuloOrNull 如果右侧参数为 0 则会返回 NULL。

语法

positiveModuloOrNull(x, y)

参数

返回值

返回 x 与最大不大于 x 的可被 y 整除的整数之间的差,或当除数为零时返回 null。

示例

positiveModuloOrNull

SELECT positiveModuloOrNull(5, 0)
\N