> ## 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)─┐
│ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ             │ ᴺᵁᴸᴸ               │
└───────────────┴───────────────┴──────────────────┴────────────────────┘
```

따라서 타입이 `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는 CASE를 두 가지 형태로 지원합니다.

1. `CASE WHEN ... THEN ... ELSE ... END`
   <br />
   이 형태는 매우 유연하며, 내부적으로 [multiIf](/ko/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 rows in set. Elapsed: 0.002 sec.
```

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`와 같은 내부적으로 동등한 표현)의 결과 타입을 결정합니다. 이는 반환 표현식의 타입이 서로 다를 때, 예를 들어 시간대나 숫자 타입이 다를 때 중요합니다.

* 결과 타입은 모든 브랜치 중에서 가장 크게 호환되는 타입을 기준으로 선택됩니다.
* 이 타입이 한 번 선택되면, 다른 모든 브랜치는 암묵적으로 해당 타입으로 CAST됩니다. 해당 로직이 런타임에 실제로 실행되지 않더라도 마찬가지입니다.
* 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` 인수는 무시됩니다.

* 배열의 경우, 사전식으로 가장 큰 배열을 반환합니다.
* `DateTime` 타입의 경우, 결과 타입은 가장 큰 타입으로 승격됩니다(예: `DateTime32`와 섞여 있으면 `DateTime64`).

<Info>
  **`NULL` 동작을 변경하려면 setting `least_greatest_legacy_null_behavior`를 사용하세요**

  버전 [24.12](/ko/resources/changelogs/oss/2024#a-id2412a-clickhouse-release-2412-2024-12-19)에서는 하위 호환되지 않는 변경이 도입되어, 이제 `NULL` 값은 무시됩니다. 이전에는 인수 중 하나가 `NULL`이면 `NULL`을 반환했습니다.
  이전 동작을 유지하려면 setting `least_greatest_legacy_null_behavior`(기본값: `false`)를 `true`로 설정하세요.
</Info>

**구문**

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

**인수**

* `x1[, x2, ...]` — 비교할 하나 이상의 값입니다. 모든 인수는 서로 비교 가능한 타입이어야 합니다. [`Any`](/ko/reference/data-types)

**반환 값**

인수 중 가장 큰 값을 반환하며, 호환되는 가장 큰 타입으로 승격됩니다. [`Any`](/ko/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 │
└────────┴─────────┘
```

**배열**

```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`가 0이 아닌 값으로 평가되면 함수는 `then` 표현식의 결과를 반환합니다.
* `cond`가 0 또는 NULL로 평가되면 `else` 표현식의 결과를 반환합니다.

[`short_circuit_function_evaluation`](/ko/reference/settings/session-settings#short_circuit_function_evaluation) 설정은 단락 평가를 사용할지 여부를 제어합니다.

이 기능이 활성화되면 `then` 표현식은 `cond`가 true인 행에서만 평가되고, `else` 표현식은 `cond`가 false인 행에서만 평가됩니다.

예를 들어, 단락 평가를 사용하면 다음 쿼리를 실행할 때 0으로 나누기 예외가 발생하지 않습니다.

```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`](/ko/reference/data-types/int-uint) 또는 [`Nullable(UInt8)`](/ko/reference/data-types/nullable) 또는 [`NULL`](/ko/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](/ko/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`](/ko/reference/data-types)

**반환 값**

인수 중 가장 작은 값을 반환합니다. 반환 타입은 호환 가능한 가장 큰 타입으로 승격됩니다. [`Any`](/ko/reference/data-types)

**예시**

**숫자형 타입**

```sql title=Query theme={null}
SELECT least(1, 2, toUInt8(3), 3.) AS result, toTypeName(result) AS type;
-- 비교를 위해 UInt8을 64비트로 승격해야 하므로 반환 유형은 Float64입니다.
```

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

**배열**

```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`](/ko/reference/operators#conditional-expression) 연산자를 더 간결하게 작성할 수 있습니다.
각 조건을 순서대로 평가합니다. 처음으로 true(0이 아니고 `NULL`이 아닌 값)인 조건에 대해 해당 브랜치 값을 반환합니다.
어떤 조건도 true가 아니면 `else` 값을 반환합니다.

설정 [`short_circuit_function_evaluation`](/ko/reference/settings/session-settings#short_circuit_function_evaluation)은
단락 평가 사용 여부를 제어합니다. 이 설정이 활성화되면 `then_i` 표현식은
`((NOT cond_1) AND ... AND (NOT cond_{i-1}) AND cond_i)`가 true인 행에서만 평가됩니다.

예를 들어, 단락 평가를 사용하면 다음 쿼리를 실행할 때 0으로 나누기 예외가 발생하지 않습니다:

```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`](/ko/reference/data-types/int-uint) 또는 [`Nullable(UInt8)`](/ko/reference/data-types/nullable) 또는 [`NULL`](/ko/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      │
└──────┴───────┴─────────────────┘
```
