Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

DISTINCT

Если указан SELECT DISTINCT, в результате запроса останутся только уникальные строки. Иными словами, из каждого набора полностью совпадающих строк в результате останется только одна строка.

Можно указать список столбцов, значения в которых должны быть уникальными: SELECT DISTINCT ON (column1, column2,...). Если столбцы не указаны, учитываются все.

Рассмотрим таблицу:

┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 2 │ 2 │ 2 │
│ 1 │ 1 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘

Использование DISTINCT без указания столбцов:

SELECT DISTINCT * FROM t1;
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 1 │ 1 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘

Использование DISTINCT с указанными столбцами:

SELECT DISTINCT ON (a,b) * FROM t1;
┌─a─┬─b─┬─c─┐
│ 1 │ 1 │ 1 │
│ 2 │ 2 │ 2 │
│ 1 │ 2 │ 2 │
└───┴───┴───┘

DISTINCT и ORDER BY

ClickHouse поддерживает использование предложений DISTINCT и ORDER BY для разных столбцов в одном запросе. Предложение DISTINCT выполняется до предложения ORDER BY.

Рассмотрим таблицу:

┌─a─┬─b─┐
│ 2 │ 1 │
│ 1 │ 2 │
│ 3 │ 3 │
│ 2 │ 4 │
└───┴───┘

Выборка данных:

SELECT DISTINCT a FROM t1 ORDER BY b ASC;
┌─a─┐
│ 2 │
│ 1 │
│ 3 │
└───┘

Выборка данных при другом направлении сортировки:

SELECT DISTINCT a FROM t1 ORDER BY b DESC;
┌─a─┐
│ 3 │
│ 1 │
│ 2 │
└───┘

Строка 2, 4 была отброшена до сортировки.

Учитывайте эту особенность реализации при составлении запросов.

Обработка NULL

DISTINCT работает с NULL так, как будто NULL — это конкретное значение и NULL==NULL. Иными словами, в результатах DISTINCT разные комбинации с NULL встречаются только один раз. Это отличается от обработки NULL в большинстве других случаев.

Альтернативы

Того же результата можно добиться, применив GROUP BY к тому же набору значений, что указан в предложении SELECT, не используя при этом агрегатные функции. Однако по сравнению с подходом GROUP BY есть несколько отличий:

  • DISTINCT можно использовать вместе с GROUP BY.
  • Если ORDER BY опущен, а LIMIT задан, выполнение запроса прекращается сразу после чтения необходимого количества различных строк.
  • Блоки данных выводятся по мере обработки, без ожидания завершения всего запроса.
Navigation