> ## 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.

> Documentação sobre Funções Condicionais

# Funções Condicionais

<div id="overview">
  ## Visão geral
</div>

<div id="using-conditional-results-directly">
  ### Usando resultados condicionais diretamente
</div>

Condicionais sempre resultam em `0`, `1` ou `NULL`. Portanto, você pode usar esses resultados diretamente assim:

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

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

<div id="null-values-in-conditionals">
  ### Valores `NULL` em condicionais
</div>

Quando valores `NULL` estão envolvidos em condicionais, o resultado também será `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)─┐
│ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ          │ ᴺᵁᴸᴸ             │ ᴺᵁᴸᴸ               │
└───────────────┴───────────────┴──────────────────┴────────────────────┘
```

Portanto, você deve construir suas consultas com cuidado se os tipos forem `Nullable`.

O exemplo a seguir demonstra isso ao não adicionar a condição de igualdade a `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">
  ### Instrução CASE
</div>

A expressão CASE no ClickHouse fornece uma lógica condicional semelhante ao operador CASE do SQL. Ela avalia condições e retorna valores com base na primeira condição que corresponde.

O ClickHouse oferece suporte a duas formas de CASE:

1. `CASE WHEN ... THEN ... ELSE ... END`
   <br />
   Esta forma oferece total flexibilidade e é implementada internamente com a função [multiIf](/pt-BR/reference/functions/regular-functions/conditional-functions#multiIf). Cada condição é avaliada de forma independente, e as expressões podem incluir valores não constantes.

```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;

-- é convertido para
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 />
   Essa forma mais compacta é otimizada para correspondência com valores constantes e usa internamente `caseWithExpression()`.

Por exemplo, o seguinte é válido:

```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;

-- é traduzido para

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.
```

Essa forma também não exige expressões de retorno constantes.

```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;

-- é traduzido para

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">
  #### Ressalvas
</div>

O ClickHouse determina o tipo de resultado de uma expressão CASE (ou seu equivalente interno, como `multiIf`) antes de avaliar quaisquer condições. Isso é importante quando as expressões de retorno diferem em tipo, como no caso de fusos horários ou tipos numéricos diferentes.

* O tipo de resultado é selecionado com base no maior tipo compatível entre todos os ramos.
* Depois que esse tipo é selecionado, todos os outros ramos são convertidos implicitamente para ele, mesmo que sua lógica nunca venha a ser executada em tempo de execução.
* Para tipos como DateTime64, em que o fuso horário faz parte da assinatura do tipo, isso pode levar a um comportamento inesperado: o primeiro fuso horário encontrado pode ser usado para todos os ramos, mesmo quando outros ramos especificam fusos horários diferentes.

Por exemplo, abaixo todas as linhas retornam o timestamp no fuso horário do primeiro ramo correspondente, ou seja, `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;

-- é convertido em

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.
```

Aqui, o ClickHouse encontra vários tipos de retorno `DateTime64(3, <timezone>)`. Ele infere o tipo comum como `DateTime64(3, 'Asia/Kolkata'` por ser o primeiro que encontra, convertendo implicitamente os outros ramos para esse tipo.

Isso pode ser resolvido convertendo para string para preservar a formatação de fuso horário desejada:

```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;

-- é traduzido como

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>

Introduzido em: v24.5.0

Restringe um valor para que permaneça dentro dos limites mínimo e máximo especificados.

Se o valor for menor que o mínimo, retorna o mínimo. Se o valor for maior que o máximo, retorna o máximo. Caso contrário, retorna o próprio valor.

Todos os argumentos devem ser de tipos comparáveis. O tipo do resultado é o maior tipo compatível entre todos os argumentos.

**Sintaxe**

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

**Argumentos**

* `value` — O valor a ser restringido. - `min` — O limite mínimo. - `max` — O limite máximo.

**Valor retornado**

Retorna o valor, restrito ao intervalo \[min, max].

**Exemplos**

**Uso básico**

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

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

**Valor abaixo do mínimo**

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

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

**Valor acima do limite máximo**

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

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

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

Introduzido em: v1.1.0

Retorna o maior valor entre os argumentos.
Argumentos `NULL` são ignorados.

* Para arrays, retorna o array lexicograficamente maior.
* Para tipos `DateTime`, o tipo do resultado é promovido ao maior tipo (por exemplo, `DateTime64` se combinado com `DateTime32`).

<Info>
  **Use a configuração `least_greatest_legacy_null_behavior` para alterar o comportamento de `NULL`**

  A versão [24.12](/pt-BR/resources/changelogs/oss/2024#a-id2412a-clickhouse-release-2412-2024-12-19) introduziu uma alteração incompatível com versões anteriores, de modo que os valores `NULL` são ignorados, enquanto antes a função retornava `NULL` se um dos argumentos fosse `NULL`.
  Para manter o comportamento anterior, defina a configuração `least_greatest_legacy_null_behavior` (padrão: `false`) como `true`.
</Info>

**Sintaxe**

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

**Argumentos**

* `x1[, x2, ...]` — Um ou mais valores a serem comparados. Todos os argumentos devem ser de tipos comparáveis. [`Any`](/pt-BR/reference/data-types)

**Valor retornado**

Retorna o maior valor entre os argumentos, promovido ao maior tipo compatível. [`Any`](/pt-BR/reference/data-types)

**Exemplos**

**Tipos numéricos**

```sql title=Query theme={null}
SELECT greatest(1, 2, toUInt8(3), 3.) AS result, toTypeName(result) AS type;
-- O tipo retornado é Float64 pois o UInt8 deve ser promovido para 64 bits para a comparação.
```

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

**Arrays**

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

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

**Tipos de DateTime**

```sql title=Query theme={null}
SELECT greatest(toDateTime32(now() + toIntervalDay(1)), toDateTime64(now(), 3));
-- O tipo retornado é DateTime64, pois o DateTime32 precisa ser promovido para 64 bits para a comparação.
```

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

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

Introduzido em: v1.1.0

Executa uma ramificação condicional.

* Se a condição `cond` for avaliada como um valor diferente de zero, a função retorna o resultado da expressão `then`.
* Se `cond` for avaliada como zero ou NULL, o resultado da expressão `else` será retornado.

A configuração [`short_circuit_function_evaluation`](/pt-BR/reference/settings/session-settings#short_circuit_function_evaluation) controla se a avaliação de curto-circuito é usada.

Se estiver habilitada, a expressão `then` será avaliada apenas nas linhas em que `cond` for true, e a expressão `else`, naquelas em que `cond` for false.

Por exemplo, com a avaliação de curto-circuito, não é lançada nenhuma exceção de divisão por zero ao executar a seguinte consulta:

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

`then` e `else` devem ser de tipos semelhantes.

**Sintaxe**

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

**Argumentos**

* `cond` — A condição avaliada. [`UInt8`](/pt-BR/reference/data-types/int-uint) ou [`Nullable(UInt8)`](/pt-BR/reference/data-types/nullable) ou [`NULL`](/pt-BR/reference/syntax#null)
* `then` — A expressão retornada se `cond` for true. - `else` — A expressão retornada se `cond` for false ou `NULL`.

**Valor retornado**

O resultado de `then` ou `else`, dependendo da condição `cond`.

**Exemplos**

**Exemplo de uso**

```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>

Introduzido em: v1.1.0

Retorna o menor valor entre os argumentos.
Argumentos `NULL` são ignorados.

* Para arrays, retorna o array lexicograficamente menor.
* Para tipos DateTime, o tipo do resultado é promovido para o maior tipo (por exemplo, DateTime64 se combinado com DateTime32).

<Info>
  **Use a configuração `least_greatest_legacy_null_behavior` para alterar o comportamento de `NULL`**

  A versão [24.12](/pt-BR/resources/changelogs/oss/2024#a-id2412a-clickhouse-release-2412-2024-12-19) introduziu uma alteração incompatível com versões anteriores, de modo que os valores `NULL` são ignorados, enquanto antes a função retornava `NULL` se um dos argumentos fosse `NULL`.
  Para manter o comportamento anterior, defina a configuração `least_greatest_legacy_null_behavior` (padrão: `false`) como `true`.
</Info>

**Sintaxe**

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

**Argumentos**

* `x1[, x2, ...]` — Um único valor ou vários valores a serem comparados. Todos os argumentos devem ser de tipos comparáveis. [`Any`](/pt-BR/reference/data-types)

**Valor retornado**

Retorna o menor valor entre os argumentos, promovido para o maior tipo compatível. [`Any`](/pt-BR/reference/data-types)

**Exemplos**

**Tipos numéricos**

```sql title=Query theme={null}
SELECT least(1, 2, toUInt8(3), 3.) AS result, toTypeName(result) AS type;
-- O tipo retornado é Float64 pois o UInt8 deve ser promovido para 64 bits para a comparação.
```

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

**Arrays**

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

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

**Tipos de DateTime**

```sql title=Query theme={null}
SELECT least(toDateTime32(now() + toIntervalDay(1)), toDateTime64(now(), 3));
-- O tipo retornado é DateTime64, pois o DateTime32 precisa ser promovido para 64 bits para a comparação.
```

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

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

Introduzido em: v1.1.0

Permite escrever o operador [`CASE`](/pt-BR/reference/operators#conditional-expression) de forma mais compacta na consulta.
Avalia cada condição em ordem. Para a primeira condição que for true (diferente de zero e não `NULL`), retorna o valor correspondente.
Se nenhuma das condições for true, retorna o valor de `else`.

A configuração [`short_circuit_function_evaluation`](/pt-BR/reference/settings/session-settings#short_circuit_function_evaluation) controla
se a avaliação de curto-circuito é usada. Se estiver ativada, a expressão `then_i` será avaliada apenas nas linhas em que
`((NOT cond_1) AND ... AND (NOT cond_{i-1}) AND cond_i)` for true.

Por exemplo, com avaliação de curto-circuito, nenhuma exceção de divisão por zero é lançada ao executar a seguinte consulta:

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

Todas as expressões dos ramos e do `else` devem ter um supertipo comum. As condições `NULL` são tratadas como falsas.

**Sintaxe**

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

**Aliases**: `caseWithoutExpression`, `caseWithoutExpr`

**Argumentos**

* `cond_N` — A enésima condição avaliada, que determina se `then_N` será retornado. [`UInt8`](/pt-BR/reference/data-types/int-uint) ou [`Nullable(UInt8)`](/pt-BR/reference/data-types/nullable) ou [`NULL`](/pt-BR/reference/syntax#null)
* `then_N` — O resultado da função quando `cond_N` é true. - `else` — O resultado da função se nenhuma das condições for true.

**Valor retornado**

Retorna o resultado de `then_N` para o `cond_N` correspondente; caso contrário, retorna o resultado de `else`.

**Exemplos**

**Exemplo de uso**

```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      │
└──────┴───────┴─────────────────┘
```
