> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentação da cláusula DISTINCT

# DISTINCT

Se `SELECT DISTINCT` for especificado, apenas linhas únicas permanecerão no resultado da consulta. Assim, de cada conjunto de linhas totalmente idênticas no resultado, apenas uma linha será mantida.

Você pode especificar a lista de colunas que devem ter valores únicos: `SELECT DISTINCT ON (column1, column2,...)`. Se as colunas não forem especificadas, todas serão levadas em consideração.

Considere a tabela:

```text theme={null}
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 2 │ 2 │ 2 │
│ 1 │ 1 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
```

Usando `DISTINCT` sem especificar colunas:

```sql theme={null}
SELECT DISTINCT * FROM t1;
```

```text theme={null}
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 1 │ 1 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
```

Usando `DISTINCT` com as colunas especificadas:

```sql theme={null}
SELECT DISTINCT ON (a,b) * FROM t1;
```

```text theme={null}
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘
```

## DISTINCT e ORDER BY

O ClickHouse permite usar as cláusulas `DISTINCT` e `ORDER BY` para colunas diferentes em uma mesma consulta. A cláusula `DISTINCT` é executada antes da cláusula `ORDER BY`.

Considere a tabela:

```text theme={null}
┌─a─┬─b─┐
│ 2 │ 1 │
│ 1 │ 2 │
│ 3 │ 3 │
│ 2 │ 4 │
└───┴───┘
```

Seleção de dados:

```sql theme={null}
SELECT DISTINCT a FROM t1 ORDER BY b ASC;
```

```text theme={null}
┌─a─┐
│ 2 │
│ 1 │
│ 3 │
└───┘
```

Selecionando dados com uma direção de ordenação diferente:

```sql theme={null}
SELECT DISTINCT a FROM t1 ORDER BY b DESC;
```

```text theme={null}
┌─a─┐
│ 3 │
│ 1 │
│ 2 │
└───┘
```

A linha `2, 4` foi descartada antes da ordenação.

Leve essa particularidade da implementação em conta ao escrever consultas.

## Processamento de NULL

`DISTINCT` funciona com [NULL](/pt-BR/reference/syntax#null) como se `NULL` fosse um valor específico e `NULL==NULL`. Em outras palavras, nos resultados de `DISTINCT`, diferentes combinações com `NULL` aparecem apenas uma vez. Isso difere do processamento de `NULL` na maioria dos outros contextos.

## Alternativas

É possível obter o mesmo resultado aplicando [GROUP BY](/pt-BR/reference/statements/select/group-by) ao mesmo conjunto de valores especificado na cláusula `SELECT`, sem usar nenhuma função de agregação. No entanto, há algumas diferenças em relação à abordagem com `GROUP BY`:

* `DISTINCT` pode ser aplicado junto com `GROUP BY`.
* Antes de a execução externa começar, uma consulta sem [ORDER BY](/pt-BR/reference/statements/select/order-by) pode parar assim que tiver lido linhas distintas suficientes para satisfazer o [LIMIT](/pt-BR/reference/statements/select/limit).
* Antes de a execução externa começar e quando `ORDER BY` é omitido, um intervalo [`LIMIT ... AFTER ... UNTIL`](/pt-BR/reference/statements/select/limit#limit-after-until) sem `ALL` também pode parar a consulta assim que o intervalo termina.
* Os blocos de dados são produzidos à medida que são processados até que a execução externa comece.

## DISTINCT em memória externa

O `DISTINCT` pode gravar dados temporários em disco para processar conjuntos de valores únicos grandes demais
para caberem na memória. Isso exige E/S de disco adicional e pode deixar as consultas mais lentas.

Duas configurações controlam quando o spill começa:

* `max_bytes_before_external_distinct` define um limiar, em bytes, da memória total da consulta. O padrão
  é `0` (desabilitado).
* `max_bytes_ratio_before_external_distinct` define uma fração da memória disponível dentro dos limites do servidor ou
  do usuário, medida no início da execução. O padrão é `0.5` e não tem efeito quando
  nenhum dos limites se aplica.

Quando ambos os limiares se aplicam, o menor prevalece. Defina as duas configurações como `0` para desabilitar o spill.

O `max_memory_usage` não afeta a razão. Para configurar o spill em relação a um limite de memória da consulta,
defina um limiar absoluto abaixo desse limite. Por exemplo, esta consulta usa um limiar de spill de 16 MiB
com um limite de memória de consulta de 256 MiB:

```sql theme={null}
SELECT DISTINCT number % 1000000 AS id
FROM numbers(2000000)
SETTINGS
    max_bytes_before_external_distinct = 16777216,
    max_bytes_ratio_before_external_distinct = 0,
    max_memory_usage = 268435456;
```

Esses limiares não limitam o consumo de memória. Deixe espaço para outras operações de processamento de consultas e para o próprio spill. O spill também pode começar mais cedo sob pressão de memória.

As linhas podem ser retornadas antes do spill, e um `LIMIT` atendido nesse estágio pode encerrar a consulta antecipadamente.
Assim que o spill começa, o restante da entrada precisa ser lido antes que os demais resultados possam ser retornados.
Se a consulta incluir `ORDER BY`, esses resultados são retornados na ordem solicitada.

Quando o `DISTINCT` usa uma entrada ordenada por um prefixo de suas chaves, não ocorre spill. Um grupo grande de linhas com o mesmo prefixo ainda pode consumir bastante memória.

Assim como em `optimize_distinct_in_order`, o spill pode deduplicar valores de ponto flutuante que têm representações binárias diferentes, mas que são iguais na comparação, incluindo `0.0` e `-0.0`, ou valores `NaN` com cargas úteis diferentes.
