Перейти к основному содержимому
Перейти к основному содержимому

Условие 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, запрос перестаёт выполняться сразу после чтения необходимого количества различных строк.
  • Блоки данных выводятся по мере обработки, без ожидания завершения всего запроса.