ClickHouse/docs/ja/sql-reference/functions/arithmetic-functions.md

534 lines
17 KiB
Markdown
Raw Normal View History

2024-11-18 02:58:58 +00:00
---
slug: /ja/sql-reference/functions/arithmetic-functions
sidebar_position: 5
sidebar_label: 算術関数
---
# 算術関数
算術関数は、`UInt8`、`UInt16`、`UInt32`、`UInt64`、`Int8`、`Int16`、`Int32`、`Int64`、`Float32`、もしくは `Float64` 型の2つのオペランドに対応します。
演算を実行する前に、両方のオペランドは結果の型にキャストされます。結果の型は以下のように決定されます(以下の関数のドキュメントで特に指定されていない限り):
- 両方のオペランドが32ビット以内であれば、結果の型のサイズは、より大きいオペランドに続く次に大きい型のサイズとなります整数サイズの昇格。例`UInt8 + UInt16 = UInt32` または `Float32 * Float32 = Float64`
- オペランドのうちの1つが64ビット以上であれば、結果の型のサイズは2つのオペランドのうち大きい方のサイズと同じになります。例`UInt32 + UInt128 = UInt128` または `Float32 * Float64 = Float64`
- オペランドのうち1つが符号付きの場合、結果の型も符号付きになります。そうでない場合は符号付きになります。例`UInt32 * Int32 = Int64`。
これらのルールにより、すべての可能な結果を表現できる最小の型が結果の型となることが保証されます。これは値の範囲境界付近でオーバーフローのリスクを伴いますが、64ビットのネイティブ整数幅を使用して計算が迅速に行われることを保証します。この挙動は、最大整数型として64ビット整数BIGINTを提供する多くの他のデータベースとの互換性も保証します。
例:
``` sql
SELECT toTypeName(0), toTypeName(0 + 0), toTypeName(0 + 0 + 0), toTypeName(0 + 0 + 0 + 0)
```
``` text
┌─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++と同様に生成されます。
## plus
2つの値 `a``b` の合計を計算します。
**構文**
```sql
plus(a, b)
```
整数と日付または時間付き日付を加算することも可能です。前者の操作は日付の日数を増加させ、後者の操作は時間付き日付の秒数を増加させます。
エイリアス: `a + b` (演算子)
## minus
2つの値 `a``b` の差を計算します。結果は常に符号付きです。
`plus` と同様に、整数から日付または時間付き日付を引くことが可能です。
**構文**
```sql
minus(a, b)
```
エイリアス: `a - b` (演算子)
## multiply
2つの値 `a``b` の積を計算します。
**構文**
```sql
multiply(a, b)
```
エイリアス: `a * b` (演算子)
## divide
2つの値 `a``b` の商を計算します。結果の型は常に [Float64](../data-types/float.md) です。整数除算は `intDiv` 関数で提供されます。
ゼロで割ると `inf`、`-inf`、または `nan` を返します。
**構文**
```sql
divide(a, b)
```
エイリアス: `a / b` (演算子)
## intDiv
2つの値 `a``b` の整数除算を行います。すなわち、商を次に小さい整数に切り下げます。
結果は被除数(最初のパラメータ)と同じ幅です。
ゼロで割るとき、商が被除数の範囲に収まらないとき、または最小の負の数を-1で割るときは例外が発生します。
**構文**
```sql
intDiv(a, b)
```
**例**
クエリ:
```sql
SELECT
intDiv(toFloat64(1), 0.001) AS res,
toTypeName(res)
```
```response
┌──res─┬─toTypeName(intDiv(toFloat64(1), 0.001))─┐
│ 1000 │ Int64 │
└──────┴─────────────────────────────────────────┘
```
```sql
SELECT
intDiv(1, 0.001) AS res,
toTypeName(res)
```
```response
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)
```
## intDivOrZero
`intDiv` と同様ですが、ゼロで割る場合や最小の負の数を-1で割る場合はゼロを返します。
**構文**
```sql
intDivOrZero(a, b)
```
## isFinite
Float32 または Float64 引数が無限でなく NaN でもない場合に1を返します。それ以外の場合、この関数は0を返します。
**構文**
```sql
isFinite(x)
```
## isInfinite
Float32 または Float64 引数が無限である場合に1を返します。それ以外の場合、この関数は0を返します。NaN に対しては0が返されることに注意してください。
**構文**
```sql
isInfinite(x)
```
## ifNotFinite
浮動小数点の値が有限かどうかをチェックします。
**構文**
```sql
ifNotFinite(x,y)
```
**引数**
- `x` — 無限かどうかをチェックする値。[Float\*](../data-types/float.md)。
- `y` — フォールバック値。[Float\*](../data-types/float.md)。
**返される値**
- `x` が有限なら `x`
- `x` が有限でなければ `y`
**例**
クエリ:
SELECT 1/0 as infimum, ifNotFinite(infimum,42)
結果:
┌─infimum─┬─ifNotFinite(divide(1, 0), 42)─┐
│ inf │ 42 │
└─────────┴───────────────────────────────┘
同様の結果を[三項演算子](../../sql-reference/functions/conditional-functions.md#ternary-operator)を使用して得ることができます: `isFinite(x) ? x : y`
## isNaN
Float32 と Float64 引数が NaN の場合に1を返し、それ以外の場合には0を返します。
**構文**
```sql
isNaN(x)
```
## modulo
2つの値 `a``b` を割った余りを計算します。
両方の入力が整数であれば、結果の型は整数です。入力の片方が浮動小数点数であれば、結果の型は [Float64](../data-types/float.md) です。
余りは C++ と同様に計算されます。負の数の場合、切り捨て除算が使用されます。
ゼロで割る場合や最小の負の数を-1で割る場合は例外が発生します。
**構文**
```sql
modulo(a, b)
```
エイリアス: `a % b` (演算子)
## moduloOrZero
[modulo](#modulo) と同様ですが、除数がゼロの場合にはゼロを返します。
**構文**
```sql
moduloOrZero(a, b)
```
## positiveModulo(a, b)
[modulo](#modulo) と同様ですが、常に非負の数を返します。
この関数は `modulo` より4-5倍遅くなります。
**構文**
```sql
positiveModulo(a, b)
```
エイリアス:
- `positive_modulo(a, b)`
- `pmod(a, b)`
**例**
クエリ:
```sql
SELECT positiveModulo(-1, 10)
```
結果:
```result
┌─positiveModulo(-1, 10)─┐
│ 9 │
└────────────────────────┘
```
## negate
`a` を反転します。結果は常に符号付きです。
**構文**
```sql
negate(a)
```
エイリアス: `-a`
## abs
`a` の絶対値を計算します。`a` が符号なし型の場合は何の効果もありません。`a` が符号付き型である場合、符号なし数を返します。
**構文**
```sql
abs(a)
```
## gcd
2つの値 `a``b` の最大公約数を返します。
ゼロで割る場合や最小の負の数を-1で割る場合は例外が発生します。
**構文**
```sql
gcd(a, b)
```
## lcm(a, b)
2つの値 `a``b` の最小公倍数を返します。
ゼロで割る場合や最小の負の数を-1で割る場合は例外が発生します。
**構文**
```sql
lcm(a, b)
```
## max2
2つの値 `a``b` のうち大きい方を返します。返される値の型は [Float64](../data-types/float.md) です。
**構文**
```sql
max2(a, b)
```
**例**
クエリ:
```sql
SELECT max2(-1, 2);
```
結果:
```result
┌─max2(-1, 2)─┐
│ 2 │
└─────────────┘
```
## min2
2つの値 `a``b` のうち小さい方を返します。返される値の型は [Float64](../data-types/float.md) です。
**構文**
```sql
min2(a, b)
```
**例**
クエリ:
```sql
SELECT min2(-1, 2);
```
結果:
```result
┌─min2(-1, 2)─┐
│ -1 │
└─────────────┘
```
## multiplyDecimal
2つの10進数 `a``b` を掛け算します。結果の値の型は [Decimal256](../data-types/decimal.md) です。
結果のスケールは `result_scale` によって明示的に指定できます。`result_scale` が指定されない場合、入力値の最大スケールが仮定されます。
この関数は通常の `multiply` よりも大幅に遅いです。結果の精度に対する制御が必要ない場合や高速な計算が望ましい場合は、`multiply` の使用を検討してください。
**構文**
```sql
multiplyDecimal(a, b[, result_scale])
```
**引数**
- `a` — 最初の値。[Decimal](../data-types/decimal.md)。
- `b` — 2番目の値。[Decimal](../data-types/decimal.md)。
- `result_scale` — 結果のスケール。[Int/UInt](../data-types/int-uint.md)。
**返される値**
- 与えられたスケールでの乗算の結果。[Decimal256](../data-types/decimal.md)。
**例**
```result
┌─multiplyDecimal(toDecimal256(-12, 0), toDecimal32(-2.1, 1), 1)─┐
│ 25.2 │
└────────────────────────────────────────────────────────────────┘
```
**通常の乗算に比べた違い:**
```sql
SELECT toDecimal64(-12.647, 3) * toDecimal32(2.1239, 4);
SELECT toDecimal64(-12.647, 3) as a, toDecimal32(2.1239, 4) as b, multiplyDecimal(a, b);
```
結果:
```result
┌─multiply(toDecimal64(-12.647, 3), toDecimal32(2.1239, 4))─┐
│ -26.8609633 │
└───────────────────────────────────────────────────────────┘
┌───────a─┬──────b─┬─multiplyDecimal(toDecimal64(-12.647, 3), toDecimal32(2.1239, 4))─┐
│ -12.647 │ 2.1239 │ -26.8609 │
└─────────┴────────┴──────────────────────────────────────────────────────────────────┘
```
```sql
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;
```
結果:
```result
┌─────────────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)
```
## divideDecimal
2つの10進数 `a``b` を除算します。結果の値の型は [Decimal256](../data-types/decimal.md) です。
結果のスケールは `result_scale` によって明示的に指定できます。`result_scale` が指定されない場合、入力値の最大スケールが仮定されます。
この関数は通常の `divide` よりも大幅に遅いです。結果の精度に対する制御が必要ない場合や高速な計算が望ましい場合は、`divide` の使用を検討してください。
**構文**
```sql
divideDecimal(a, b[, result_scale])
```
**引数**
- `a` — 最初の値:[Decimal](../data-types/decimal.md)。
- `b` — 2番目の値[Decimal](../data-types/decimal.md)。
- `result_scale` — 結果のスケール:[Int/UInt](../data-types/int-uint.md)。
**返される値**
- 与えられたスケールでの除算の結果。[Decimal256](../data-types/decimal.md)。
**例**
```result
┌─divideDecimal(toDecimal256(-12, 0), toDecimal32(2.1, 1), 10)─┐
│ -5.7142857142 │
└──────────────────────────────────────────────────────────────┘
```
**通常の除算に比べた違い:**
```sql
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);
```
結果:
```result
┌─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 │
└─────┴─────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘
```
```sql
SELECT toDecimal64(-12, 0) / toDecimal32(2.1, 1);
SELECT toDecimal64(-12, 0) as a, toDecimal32(2.1, 1) as b, divideDecimal(a, b, 1), divideDecimal(a, b, 5);
```
結果:
```result
DB::Exception: Decimal result's scale is less than argument's one: While processing toDecimal64(-12, 0) / toDecimal32(2.1, 1). (ARGUMENT_OUT_OF_BOUND)
┌───a─┬───b─┬─divideDecimal(toDecimal64(-12, 0), toDecimal32(2.1, 1), 1)─┬─divideDecimal(toDecimal64(-12, 0), toDecimal32(2.1, 1), 5)─┐
│ -12 │ 2.1 │ -5.7 │ -5.71428 │
└─────┴─────┴────────────────────────────────────────────────────────────┴────────────────────────────────────────────────────────────┘
```
## byteSwap
整数のバイトを反転します。すなわち、その[エンディアン](https://en.wikipedia.org/wiki/Endianness)を変更します。
**構文**
```sql
byteSwap(a)
```
**例**
```sql
byteSwap(3351772109)
```
結果:
```result
┌─byteSwap(3351772109)─┐
│ 3455829959 │
└──────────────────────┘
```
上記の例は次のようにして導き出せます:
1. 10進数の整数をビッグエンディアン形式の16進数形式に変換します。例: 3351772109 -> C7 C7 FB CD (4バイト)
2. バイトを反転します。例: C7 C7 FB CD -> CD FB C7 C7
3. 結果をビッグエンディアンを仮定して整数に変換します。例: CD FB C7 C7 -> 3455829959
この関数の一つのユースケースはIPv4の反転です
```result
┌─toIPv4(byteSwap(toUInt32(toIPv4('205.251.199.199'))))─┐
│ 199.199.251.205 │
└───────────────────────────────────────────────────────┘
```