> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> 条件付き関数のドキュメント

# 条件付き関数

<div id="overview">
  ## 概要
</div>

<div id="using-conditional-results-directly">
  ### 条件式の結果をそのまま使用する
</div>

条件式の結果は常に `0`、`1`、または `NULL` です。そのため、条件式の結果は次のようにそのまま使用できます。

```sql theme={null}
SELECT left < right AS is_small
FROM LEFT_RIGHT

┌─is_small─┐
│     ᴺᵁᴸᴸ │
│        1 │
│        0 │
│        0 │
│     ᴺᵁᴸᴸ │
└──────────┘
```

<div id="null-values-in-conditionals">
  ### 条件式における NULL 値
</div>

条件式に NULL 値が含まれる場合、結果も NULL になります。

```sql theme={null}
SELECT
    NULL < 1,
    2 < NULL,
    NULL < NULL,
    NULL = NULL

┌─less(NULL, 1)─┬─less(2, NULL)─┬─less(NULL, NULL)─┬─equals(NULL, NULL)─┐
│ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ             │ ᴺᵁᴸᴸ               │
└───────────────┴───────────────┴──────────────────┴────────────────────┘
```

したがって、types が `Nullable` の場合は、クエリを慎重に組み立てる必要があります。

次の例では、`multiIf` に等価条件を追加していないために失敗することを示しています。

```sql theme={null}
SELECT
    left,
    right,
    multiIf(left < right, 'left is smaller', left > right, 'right is smaller', 'Both equal') AS faulty_result
FROM LEFT_RIGHT

┌─left─┬─right─┬─faulty_result────┐
│ ᴺᵁᴸᴸ │     4 │ Both equal       │
│    1 │     3 │ left is smaller  │
│    2 │     2 │ Both equal       │
│    3 │     1 │ right is smaller │
│    4 │  ᴺᵁᴸᴸ │ Both equal       │
└──────┴───────┴──────────────────┘
```

<div id="case-statement">
  ### CASE ステートメント
</div>

ClickHouse の CASE 式は、SQL の CASE 演算子と同様の条件分岐ロジックを提供します。条件を評価し、最初に一致した条件に基づいて値を返します。

ClickHouse は 2 種類の CASE をサポートしています。

1. `CASE WHEN ... THEN ... ELSE ... END`
   <br />
   この形式では高い柔軟性があり、内部的には [multiIf](/ja/reference/functions/regular-functions/conditional-functions#multiIf) 関数を使って実装されています。各条件は個別に評価され、式には定数以外の値を含めることもできます。

```sql theme={null}
SELECT
    number,
    CASE
        WHEN number % 2 = 0 THEN number + 1
        WHEN number % 2 = 1 THEN number * 10
        ELSE number
    END AS result
FROM system.numbers
WHERE number < 5;

-- 次のように変換されます
SELECT
    number,
    multiIf((number % 2) = 0, number + 1, (number % 2) = 1, number * 10, number) AS result
FROM system.numbers
WHERE number < 5

┌─number─┬─result─┐
│      0 │      1 │
│      1 │     10 │
│      2 │      3 │
│      3 │     30 │
│      4 │      5 │
└────────┴────────┘

5 行がセットに含まれています。経過時間: 0.002 秒。
```

2. `CASE <expr> WHEN <val1> THEN ... WHEN <val2> THEN ... ELSE ... END`
   <br />
   このより簡潔な形式は、定数値との一致に最適化されており、内部的には `caseWithExpression()` を使用します。

たとえば、次のように記述できます。

```sql theme={null}
SELECT
    number,
    CASE number
        WHEN 0 THEN 100
        WHEN 1 THEN 200
        ELSE 0
    END AS result
FROM system.numbers
WHERE number < 3;

-- 次のように変換されます

SELECT
    number,
    caseWithExpression(number, 0, 100, 1, 200, 0) AS result
FROM system.numbers
WHERE number < 3

┌─number─┬─result─┐
│      0 │    100 │
│      1 │    200 │
│      2 │      0 │
└────────┴────────┘

3 rows in set. Elapsed: 0.002 sec.
```

この形式では、返される式も定数である必要はありません。

```sql theme={null}
SELECT
    number,
    CASE number
        WHEN 0 THEN number + 1
        WHEN 1 THEN number * 10
        ELSE number
    END
FROM system.numbers
WHERE number < 3;

-- 次のように変換されます

SELECT
    number,
    caseWithExpression(number, 0, number + 1, 1, number * 10, number)
FROM system.numbers
WHERE number < 3

┌─number─┬─caseWithExpr⋯0), number)─┐
│      0 │                        1 │
│      1 │                       10 │
│      2 │                        2 │
└────────┴──────────────────────────┘

3 rows in set. Elapsed: 0.001 sec.
```

<div id="caveats">
  #### 注意点
</div>

ClickHouse は、CASE 式 (または `multiIf` などの内部的に等価な処理) の結果の型を、条件を評価する前に決定します。これは、返される式の型が異なる場合、たとえばタイムゾーンや数値型が異なる場合に重要です。

* 結果の型は、すべての分岐の中で互換性のある最も大きい型に基づいて選択されます。
* いったんこの型が選択されると、他のすべての分岐は暗黙的にその型にキャストされます。実行時にそのロジックが決して実行されない場合でも同様です。
* DateTime64 のようにタイムゾーンが型シグネチャの一部である型では、これによって予期しない動作が生じることがあります。ほかの分岐で異なるタイムゾーンを指定していても、最初に見つかったタイムゾーンがすべての分岐に使用される場合があります。

たとえば、以下ではすべての行が、最初に一致した分岐のタイムゾーン、すなわち `Asia/Kolkata` のタイムスタンプを返します

```sql theme={null}
SELECT
    number,
    CASE
        WHEN number = 0 THEN fromUnixTimestamp64Milli(0, 'Asia/Kolkata')
        WHEN number = 1 THEN fromUnixTimestamp64Milli(0, 'America/Los_Angeles')
        ELSE fromUnixTimestamp64Milli(0, 'UTC')
    END AS tz
FROM system.numbers
WHERE number < 3;

-- 次のように変換されます

SELECT
    number,
    multiIf(number = 0, fromUnixTimestamp64Milli(0, 'Asia/Kolkata'), number = 1, fromUnixTimestamp64Milli(0, 'America/Los_Angeles'), fromUnixTimestamp64Milli(0, 'UTC')) AS tz
FROM system.numbers
WHERE number < 3

┌─number─┬──────────────────────tz─┐
│      0 │ 1970-01-01 05:30:00.000 │
│      1 │ 1970-01-01 05:30:00.000 │
│      2 │ 1970-01-01 05:30:00.000 │
└────────┴─────────────────────────┘

3 rows in set. Elapsed: 0.011 sec.
```

ここで ClickHouse は、複数の `DateTime64(3, <timezone>)` 戻り値型を認識します。最初に見つかった `DateTime64(3, 'Asia/Kolkata'` を共通型として推論し、他の分岐を暗黙的にこの型にキャストします。

これは、意図したタイムゾーンのフォーマットを保持するために、文字列に変換することで対処できます:

```sql theme={null}
SELECT
    number,
    multiIf(
        number = 0, formatDateTime(fromUnixTimestamp64Milli(0), '%F %T', 'Asia/Kolkata'),
        number = 1, formatDateTime(fromUnixTimestamp64Milli(0), '%F %T', 'America/Los_Angeles'),
        formatDateTime(fromUnixTimestamp64Milli(0), '%F %T', 'UTC')
    ) AS tz
FROM system.numbers
WHERE number < 3;

-- 次のように変換されます

SELECT
    number,
    multiIf(number = 0, formatDateTime(fromUnixTimestamp64Milli(0), '%F %T', 'Asia/Kolkata'), number = 1, formatDateTime(fromUnixTimestamp64Milli(0), '%F %T', 'America/Los_Angeles'), formatDateTime(fromUnixTimestamp64Milli(0), '%F %T', 'UTC')) AS tz
FROM system.numbers
WHERE number < 3

┌─number─┬─tz──────────────────┐
│      0 │ 1970-01-01 05:30:00 │
│      1 │ 1969-12-31 16:00:00 │
│      2 │ 1970-01-01 00:00:00 │
└────────┴─────────────────────┘

3 rows in set. Elapsed: 0.002 sec.
```

{/*AUTOGENERATED_START*/}

<div id="clamp">
  ## clamp
</div>

導入バージョン: v24.5.0

値を指定された最小値と最大値の範囲内に制限します。

値が最小値未満の場合は最小値を返します。値が最大値を超える場合は最大値を返します。それ以外の場合は、値自体を返します。

すべての引数は比較可能な型である必要があります。結果の型は、すべての引数の中で最も広い互換型になります。

**構文**

```sql theme={null}
clamp(value, min, max)
```

**引数**

* `value` — 制限する値。 - `min` — 下限値。 - `max` — 上限値。

**戻り値**

\[min, max] の範囲に制限された値を返します。

**例**

**基本的な使い方**

```sql title=Query theme={null}
SELECT clamp(5, 1, 10) AS result;
```

```response title=Response theme={null}
┌─result─┐
│      5 │
└────────┘
```

**値が最小値未満です**

```sql title=Query theme={null}
SELECT clamp(-3, 0, 7) AS result;
```

```response title=Response theme={null}
┌─result─┐
│      0 │
└────────┘
```

**最大値を超えた値**

```sql title=Query theme={null}
SELECT clamp(15, 0, 7) AS result;
```

```response title=Response theme={null}
┌─result─┐
│      7 │
└────────┘
```

<div id="greatest">
  ## greatest
</div>

導入バージョン: v1.1.0

引数の中で最も大きい値を返します。
`NULL` 引数は無視されます。

* Array の場合、辞書順で最大の配列を返します。
* `DateTime` 型の場合、結果の型は最大の型に昇格されます (例: `DateTime32` と混在している場合は `DateTime64`) 。

<Info>
  **`NULL` の動作を変更するには、設定 `least_greatest_legacy_null_behavior` を使用します**

  バージョン [24.12](/ja/resources/changelogs/oss/2024#a-id2412a-clickhouse-release-2412-2024-12-19) では後方互換性のない変更が導入され、`NULL` 値は無視されるようになりました。以前は、引数のいずれかが `NULL` の場合に `NULL` を返していました。
  従来の動作を維持するには、設定 `least_greatest_legacy_null_behavior` (デフォルト: `false`) を `true` に設定してください。
</Info>

**構文**

```sql theme={null}
greatest(x1[, x2, ...])
```

**引数**

* `x1[, x2, ...]` — 比較対象の 1 つまたは複数の値。すべての引数は比較可能な型である必要があります。[`Any`](/ja/reference/data-types)

**戻り値**

引数の中で最も大きい値を返します。戻り値は、互換性のある最も広い型に昇格されます。[`Any`](/ja/reference/data-types)

**例**

**数値型**

```sql title=Query theme={null}
SELECT greatest(1, 2, toUInt8(3), 3.) AS result, toTypeName(result) AS type;
-- UInt8 を比較のために 64 ビットに昇格させる必要があるため、返される型は Float64 です。
```

```response title=Response theme={null}
┌─result─┬─type────┐
│      3 │ Float64 │
└────────┴─────────┘
```

**Array**

```sql title=Query theme={null}
SELECT greatest(['hello'], ['there'], ['world']);
```

```response title=Response theme={null}
┌─greatest(['hello'], ['there'], ['world'])─┐
│ ['world']                                 │
└───────────────────────────────────────────┘
```

**DateTime型**

```sql title=Query theme={null}
SELECT greatest(toDateTime32(now() + toIntervalDay(1)), toDateTime64(now(), 3));
-- 返される型はDateTime64です。比較のためにDateTime32を64ビットに昇格させる必要があるためです。
```

```response title=Response theme={null}
┌─greatest(toD⋯(now(), 3))─┐
│  2025-05-28 15:50:53.000 │
└──────────────────────────┘
```

<div id="if">
  ## if
</div>

導入バージョン: v1.1.0

条件分岐を行います。

* 条件 `cond` が非ゼロの値として評価された場合、この関数は式 `then` の結果を返します。
* `cond` が 0 または NULL として評価された場合は、式 `else` の結果が返されます。

設定 [`short_circuit_function_evaluation`](/ja/reference/settings/session-settings#short_circuit_function_evaluation) では、短絡評価を使用するかどうかを制御します。

有効な場合、式 `then` は `cond` が true の行でのみ評価され、式 `else` は `cond` が false の行でのみ評価されます。

たとえば、短絡評価を使用すると、次のクエリを実行してもゼロ除算の例外はスローされません。

```sql theme={null}
SELECT if(number = 0, 0, intDiv(42, number)) FROM numbers(10)
```

`then` と `else` は同様の型である必要があります。

**構文**

```sql theme={null}
if(cond, then, else)
```

**引数**

* `cond` — 評価される条件。[`UInt8`](/ja/reference/data-types/int-uint)、[`Nullable(UInt8)`](/ja/reference/data-types/nullable)、または [`NULL`](/ja/reference/syntax#null)
* `then` — `cond` が true の場合に返される式。 - `else` — `cond` が false または `NULL` の場合に返される式。

**戻り値**

条件 `cond` に応じて、`then` または `else` の式の結果を返します。

**例**

**使用例**

```sql title=Query theme={null}
SELECT if(1, 2 + 2, 2 + 6) AS res;
```

```response title=Response theme={null}
┌─res─┐
│   4 │
└─────┘
```

<div id="least">
  ## least
</div>

導入バージョン: v1.1.0

引数の中で最も小さい値を返します。
`NULL` の引数は無視されます。

* 配列の場合、辞書順で最小の配列を返します。
* DateTime型の場合、結果の型は最大の型に昇格されます (たとえば、DateTime32 と混在している場合は DateTime64) 。

<Info>
  **`NULL` の動作を変更するには、設定 `least_greatest_legacy_null_behavior` を使用します**

  バージョン [24.12](/ja/resources/changelogs/oss/2024#a-id2412a-clickhouse-release-2412-2024-12-19) では、`NULL` 値が無視されるようになる後方互換性のない変更が導入されました。以前は、引数のいずれかが `NULL` の場合、`NULL` を返していました。
  以前の動作を維持するには、設定 `least_greatest_legacy_null_behavior` (デフォルト: `false`) を `true` に設定してください。
</Info>

**構文**

```sql theme={null}
least(x1[, x2, ...])
```

**引数**

* `x1[, x2, ...]` — 比較する単一の値または複数の値。すべての引数は、相互に比較可能な型である必要があります。[`Any`](/ja/reference/data-types)

**戻り値**

引数の中で最も小さい値を返します。戻り値の型は、互換性のある最も大きい型に昇格されます。[`Any`](/ja/reference/data-types)

**例**

**数値型**

```sql title=Query theme={null}
SELECT least(1, 2, toUInt8(3), 3.) AS result, toTypeName(result) AS type;
-- 返される型はFloat64です。比較のためにUInt8を64ビットに昇格させる必要があるためです。
```

```response title=Response theme={null}
┌─result─┬─type────┐
│      1 │ Float64 │
└────────┴─────────┘
```

**Array**

```sql title=Query theme={null}
SELECT least(['hello'], ['there'], ['world']);
```

```response title=Response theme={null}
┌─least(['hell⋯ ['world'])─┐
│ ['hello']                │
└──────────────────────────┘
```

**DateTime型**

```sql title=Query theme={null}
SELECT least(toDateTime32(now() + toIntervalDay(1)), toDateTime64(now(), 3));
-- 返される型はDateTime64です。比較のためにDateTime32を64ビットに昇格させる必要があるためです。
```

```response title=Response theme={null}
┌─least(toDate⋯(now(), 3))─┐
│  2025-05-27 15:55:20.000 │
└──────────────────────────┘
```

<div id="multiIf">
  ## multiIf
</div>

導入バージョン: v1.1.0

クエリ内で [`CASE`](/ja/reference/operators#conditional-expression) 演算子をより簡潔に記述できます。
各条件は順番に評価されます。最初に true (非ゼロかつ `NULL` ではない) となった条件に対応する分岐値を返します。
いずれの条件も true でない場合は、`else` の値を返します。

設定 [`short_circuit_function_evaluation`](/ja/reference/settings/session-settings#short_circuit_function_evaluation) は、
短絡評価を使用するかどうかを制御します。有効な場合、`then_i` 式は
`((NOT cond_1) AND ... AND (NOT cond_{i-1}) AND cond_i)` が true になる行でのみ評価されます。

たとえば、短絡評価を使用すると、次のクエリを実行してもゼロ除算例外は発生しません。

```sql theme={null}
SELECT multiIf(number = 2, intDiv(1, number), number = 5) FROM numbers(10)
```

すべての分岐式と else 式は、共通のスーパータイプである必要があります。条件が `NULL` の場合は false として扱われます。

**構文**

```sql theme={null}
multiIf(cond_1, then_1, cond_2, then_2, ..., else)
```

**別名**: `caseWithoutExpression`, `caseWithoutExpr`

**引数**

* `cond_N` — `then_N` を返すかどうかを制御する、N 番目に評価される条件。[`UInt8`](/ja/reference/data-types/int-uint) または [`Nullable(UInt8)`](/ja/reference/data-types/nullable) または [`NULL`](/ja/reference/syntax#null)
* `then_N` — `cond_N` が true の場合に返される関数の結果。 - `else` — どの条件も true でない場合の関数の結果。

**戻り値**

一致した `cond_N` に対応する `then_N` の結果を返し、どれにも一致しない場合は `else` の結果を返します。

**例**

**使用例**

```sql title=Query theme={null}
CREATE TABLE LEFT_RIGHT (left Nullable(UInt8), right Nullable(UInt8)) ENGINE = Memory;
INSERT INTO LEFT_RIGHT VALUES (NULL, 4), (1, 3), (2, 2), (3, 1), (4, NULL);

SELECT
    left,
    right,
    multiIf(left < right, 'left is smaller', left > right, 'left is greater', left = right, 'Both equal', 'Null value') AS result
FROM LEFT_RIGHT;
```

```response title=Response theme={null}
┌─left─┬─right─┬─result──────────┐
│ ᴺᵁᴸᴸ │     4 │ Null value      │
│    1 │     3 │ left is smaller │
│    2 │     2 │ Both equal      │
│    3 │     1 │ left is greater │
│    4 │  ᴺᵁᴸᴸ │ Null value      │
└──────┴───────┴─────────────────┘
```
