メインコンテンツへスキップ
メインコンテンツへスキップ

算術関数

概要

算術関数は、UInt8UInt16UInt32UInt64Int8Int16Int32Int64Float32Float64 型のいずれか 2 つのオペランドに対して動作します。

演算を実行する前に、両方のオペランドは結果の型にキャストされます。結果の型は次のように決定されます(この後の関数ドキュメントで別途指定されていない限り):

  • 両方のオペランドが 32 ビット以下の場合、結果の型のサイズは、2 つのオペランドのうちビット幅が大きい方の「次に大きい」型のサイズになります(整数サイズの昇格)。たとえば、UInt8 + UInt16 = UInt32Float32 * Float32 = Float64 です。
  • オペランドの一方が 64 ビット以上の場合、結果の型のサイズは、2 つのオペランドのうちビット幅が大きい方と同じサイズになります。たとえば、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

avg2

導入バージョン: v25.11

指定された引数の平均値を計算して返します。 数値型および日時型をサポートします。

構文

avg2(x1, x2])

引数

  • x1, x2] — 平均値を計算するための 2 つの値を受け取ります。

戻り値

指定された引数の平均値を、互換性のある型のうち最も広い型に型昇格したうえで返します。

使用例

数値型

SELECT avg2(toUInt8(3), 1.0) AS result, toTypeName(result) AS type;
-- 返される型はFloat64です。比較のためにUInt8を64ビットに昇格する必要があるためです。
┌─result─┬─type────┐
│      2 │ Float64 │
└────────┴─────────┘

Decimal 型

SELECT avg2(toDecimal32(1, 2), 2) AS result, toTypeName(result) AS type;
┌─result─┬─type──────────┐
│    1.5 │ Decimal(9, 2) │
└────────┴───────────────┘

日付型

SELECT avg2(toDate('2025-01-01'), toDate('2025-01-05')) AS result, toTypeName(result) AS type;
┌─────result─┬─type─┐
│ 2025-01-03 │ Date │
└────────────┴──────┘

DateTime型

SELECT avg2(toDateTime('2025-01-01 00:00:00'), toDateTime('2025-01-03 12:00:00')) AS result, toTypeName(result) AS type;
┌──────────────result─┬─type─────┐
│ 2025-01-02 06:00:00 │ DateTime │
└─────────────────────┴──────────┘

Time64型

SELECT avg2(toTime64('12:00:00', 0), toTime64('14:00:00', 0)) AS result, toTypeName(result) AS type;
┌───result─┬─type──────┐
│ 13:00:00 │ Time64(0) │
└──────────┴───────────┘

byteSwap

導入バージョン: v23.10

整数のバイト順を反転し、その結果としてエンディアンを変更します。

以下の例は次の手順で求めることができます。

  1. 10進整数をビッグエンディアンでの16進表現に変換する。例: 3351772109 -> C7 C7 FB CD(4バイト)
  2. バイト列を反転する。例: C7 C7 FB CD -> CD FB C7 C7
  3. 結果をビッグエンディアンとして整数に戻す。例: CD FB C7 C7 -> 3455829959

この関数のユースケースの 1 つは、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

2つの値 ab の商を計算します。結果の型は常に Float64 です。 整数除算は intDiv 関数で提供されます。

注記

0 で除算した場合は inf-inf、または nan を返します。

構文

divide(x, y)

引数

  • x — 被除数、y — 除数

返される値

x を y で割った結果の商

2 つの数値を割る

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

ゼロ除算

SELECT divide(25,0)
inf

divideDecimal

導入バージョン: v22.12

2つの Decimal に対して除算を行います。結果の値の型は Decimal256 になります。 結果のスケールは result_scale 引数(範囲 [0, 76] の定数 Integer)で明示的に指定できます。指定しない場合、結果のスケールは与えられた引数のスケールの最大値になります。

注記

これらの関数は通常の divide 関数と比べて大幅に低速です。 精度の厳密な制御が不要な場合や、高速な計算が必要な場合は、divide の使用を検討してください。

構文

divideDecimal(x, y[, result_scale])

引数

  • x — 1 つ目の値: Decimal. - y — 2 つ目の値: 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 と同様ですが、0 で除算した場合は NULL を返します。

構文

divideOrNull(x, y)

引数

  • x — 被除数、y — 除数

戻り値

x を y で割った商、または NULL。

ゼロで割る場合

SELECT divideOrNull(25, 0)
\N

gcd

導入: v1.1

2 つの値 a と b の最大公約数を返します。

0 で割った場合、または最小の負の値を -1 で割った場合には、例外がスローされます。

構文

gcd(x, y)

引数

  • x — 第1の整数、y — 第2の整数

戻り値

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

2 つの値 xy で整数除算します。言い換えると、商を直前のより小さい整数値に切り下げて計算します。

結果のビット幅は被除数(第 1 引数)と同じになります。

0 で除算した場合、商が被除数の表現範囲に収まらない場合、または表現可能な最小の負の値を -1 で除算した場合には、例外がスローされます。

構文

intDiv(x, y)

引数

  • x — 左辺のオペランド。
  • y — 右辺のオペランド。

戻り値

xy の整数除算の結果。

2 つの浮動小数点数の整数除算

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)
サーバーから例外を受信しました (バージョン 23.2.1):
Code: 153. DB::Exception: Received from localhost:9000. DB::Exception:
整数除算を実行できません。無限大または過大な数値が生成されるためです: intDiv(1, 0.001) AS res, toTypeName(res) の処理中。
(ILLEGAL_DIVISION)

intDivOrNull

導入バージョン: v25.5

intDiv と同様ですが、ゼロ除算を行う場合、または最小の負の整数値をマイナス 1 で割る場合に NULL を返します。

構文

intDivOrNull(x, y)

引数

  • x — 左側のオペランド。(U)Int*
  • y — 右側のオペランド。(U)Int*

戻り値

xy の整数除算の結果、または NULL。

使用例

0 による整数除算

SELECT intDivOrNull(1, 0)
\N

最小の負の数を −1 で割る

SELECT intDivOrNull(-9223372036854775808, -1)
\N

intDivOrZero

導入バージョン: v1.1

intDiv と同じですが、ゼロで除算した場合、または最小の負の整数を -1 で除算した場合に 0 を返します。

構文

intDivOrZero(a, b)

引数

  • a — 左側のオペランド。(U)Int*
  • b — 右側のオペランド。(U)Int*

戻り値

a を b で整数除算した結果、または 0。

0 での整数除算

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、それ以外(NaN を含む)の場合は 0

使用例

数値が無限大かどうかを判定する

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

isNaN

導入バージョン: v1.1

浮動小数点数型の Float32 および Float64 の引数が NaN の場合は 1 を返し、それ以外の場合は 0 を返します。

構文

isNaN(x)

引数

  • xNaN かどうかを判定する対象。Float*

戻り値

NaN の場合は 1、それ以外は 0

使用例

SELECT isNaN(NaN)
1

lcm

導入バージョン: v1.1

2つの値 xy の最小公倍数を返します。

ゼロで除算した場合、または最小の負の値をマイナス1で除算した場合に例外がスローされます。

構文

lcm(x, y)

引数

戻り値

xy の最小公倍数を返します。(U)Int*

使用例

SELECT lcm(6, 8)
24

max2

導入されたバージョン: v21.11

2 つの数値 xy のうち、大きい方を返します。

構文

max2(x, y)

引数

戻り値

xy のうち大きい方の値を返します。Float64

使用例

SELECT max2(-1, 2)
2

midpoint

導入バージョン: v25.11

指定された引数の平均値を計算して返します。 数値型および時間データ型をサポートします。

構文

midpoint(x1[, x2, ...])

引数

  • x1[, x2, ...] — 平均を計算するための単一値または複数の値を受け取ります。

返り値

指定された引数の平均値を返し、その値は互換性のある型のうち最も大きい型に昇格されます。

数値型

SELECT midpoint(1, toUInt8(3), 0.5) AS result, toTypeName(result) AS type;
-- 返される型はFloat64です。比較のためにUInt8を64ビットに昇格する必要があるためです。
┌─result─┬─type────┐
│    1.5 │ Float64 │
└────────┴─────────┘

Decimal 型

SELECT midpoint(toDecimal32(1.5, 2), toDecimal32(1, 1), 2) AS result, toTypeName(result) AS type;
┌─result─┬─type──────────┐
│    1.5 │ Decimal(9, 2) │
└────────┴───────────────┘

日付型

SELECT midpoint(toDate('2025-01-01'), toDate('2025-01-05')) AS result, toTypeName(result) AS type;
┌─────result─┬─type─┐
│ 2025-01-03 │ Date │
└────────────┴──────┘

DateTime 型

SELECT midpoint(toDateTime('2025-01-01 00:00:00'), toDateTime('2025-01-03 12:00:00')) AS result, toTypeName(result) AS type;
┌──────────────result─┬─type─────┐
│ 2025-01-02 06:00:00 │ DateTime │
└─────────────────────┴──────────┘

Time64 型

SELECT midpoint(toTime64('12:00:00', 0), toTime64('14:00:00', 0)) AS result, toTypeName(result) AS type;
┌───result─┬─type──────┐
│ 13:00:00 │ Time64(0) │
└──────────┴───────────┘

min2

導入バージョン: v21.11

2つの数値 xy のうち小さい方を返します。

構文

min2(x, y)

引数

戻り値

xy のうち小さい方の値を返します。Float64

使用例

SELECT min2(-1, 2)
-1

minus

導入バージョン: v1.1

2 つの値 ab の差を計算します。結果は常に符号付きです。 plus と同様に、日付または日時から整数を減算できます。 さらに、日時同士の減算もサポートされており、その時間差が結果として得られます。

構文

minus(x, y)

引数

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

戻り値

x から y を引いた結果

2 つの数値の減算

SELECT minus(10, 5)
5

整数と日付の減算

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

modulo

導入: v1.1

2つの値 a と b に対して、a を b で割った余りを計算します。

両方の入力が整数の場合、結果の型は整数型です。入力の一方が 浮動小数点数の場合、結果の型は Float64 になります。

余りは C++ と同様に計算されます。負の数に対しては切り捨て除算が使用されます。

ゼロで除算した場合、または最小の負の値を -1 で除算した場合は、例外がスローされます。

構文

modulo(a, b)

エイリアス: mod

引数

  • a — 被除数
  • b — 除数(法)

戻り値

a % b の剰余

使用例

SELECT modulo(5, 2)
1

moduloOrNull

導入バージョン: v25.5

ab で割ったときの剰余を計算します。関数 modulo と似ていますが、右側の引数が 0 の場合には moduloOrNull は NULL を返します。

構文

moduloOrNull(x, y)

別名: modOrNull

引数

戻り値

xy で割った余り、または除数がゼロの場合は null を返します。

ゼロ除算時の moduloOrNull

SELECT moduloOrNull(5, 0)
\N

moduloOrZero

導入バージョン: v20.3

modulo に似ていますが、割る数が 0 の場合に例外を送出する modulo 関数とは異なり、0 を返します。

構文

moduloOrZero(a, b)

引数

返される値

a % b の余りを返します。除数が 0 の場合は 0 を返します。

使用例

SELECT moduloOrZero(5, 0)
0

multiply

導入バージョン: v1.1

2つの値 xy の積を計算します。

構文

multiply(x, y)

引数

戻り値

x と y の積を返します。

2 つの数値の乗算

SELECT multiply(5,5)
25

multiplyDecimal

導入バージョン: v22.12

2つの Decimal 値に対して乗算を行います。結果の値の型は Decimal256 になります。 結果のスケールは result_scale 引数(範囲 [0, 76] の定数の整数値)で明示的に指定できます。指定しない場合、結果のスケールは引数として与えた値のスケールの最大値になります。

注記

これらの関数は通常の multiply よりもかなり遅く動作します。 厳密な精度の制御が不要な場合や、高速な計算が必要な場合は multiply の利用を検討してください。

構文

multiplyDecimal(a, b[, result_scale])

引数

  • a — 1つ目の値。Decimal
  • b — 2つ目の値。Decimal
  • result_scale — 結果のスケール(桁数)。(U)Int*

戻り値

指定したスケールでの乗算の結果。型: 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 │
└──────────────────────────────────────────────────────────────────┘

Decimal オーバーフロー

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 │
└───────────────┴───────────────┴───────────────────────────────────────────────────────────────────────────────┘
サーバーから例外を受信しました (バージョン 22.11.1):
コード: 407. DB::Exception: localhost:9000 から受信しました。DB::Exception: Decimal演算オーバーフロー:
toDecimal64(-12.647987876, 9) AS a, toDecimal64(123.967645643, 9) AS b, a * b の処理中。(DECIMAL_OVERFLOW)

negate

導入バージョン: v1.1

引数 x の符号を反転します。結果は常に符号付きになります。

構文

negate(x)

引数

  • x — 符号を反転する対象の値。

返り値

x の符号を反転した値 -x を返します。

使用例

SELECT negate(10)
-10

plus

導入バージョン: v1.1

2 つの値 xy の合計を計算します。別名: x + y(演算子)。 整数と日付、または日時を加算することもできます。前者の 演算では日付に日数が加算され、後者の演算では日時に秒数が加算されます。

構文

plus(x, y)

引数

  • x — 左側のオペランド。 - y — 右側のオペランド。

戻り値

x と y の合計を返します。

2 つの数値を加算する

SELECT plus(5,5)
10

整数型と日付型を加算する

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

positiveModulo

導入されたバージョン: v22.11

xy で割ったときの余りを計算します。関数 modulo と似ていますが、positiveModulo は常に非負の数を返します。

構文

positiveModulo(x, y)

別名: positive_modulo, pmod

引数

返される値

x 以下で y で割り切れる最も近い数値と x との差を返します。

使用例

SELECT positiveModulo(-1, 10)
9

positiveModuloOrNull

導入バージョン: v25.5

ab で割った余りを計算します。positiveModulo 関数と似ていますが、右側の引数が 0 の場合は、positiveModuloOrNull は NULL を返します。

構文

positiveModuloOrNull(x, y)

別名: positive_modulo_or_null, pmodOrNull

引数

戻り値

x 以下で y で割り切れる最も近い整数と x との差を返します。除数がゼロの場合は null を返します。

positiveModuloOrNull

SELECT positiveModuloOrNull(5, 0)
\N