Skip to content
ClickHouse Docs
ClickHouse DocsClickHouse Docs

WHERE

Предложение WHERE позволяет фильтровать данные, поступающие из предложения FROM оператора SELECT.

Если есть предложение WHERE, за ним должно следовать выражение типа UInt8. Строки, для которых это выражение вычисляется в 0, исключаются из дальнейших преобразований или из результата.

Выражение после предложения WHERE часто используется с операторами сравнения и логическими операторами, а также с одной из множества обычных функций.

При вычислении выражения WHERE могут использоваться индексы и отсечение партиций, если базовый движок таблицы это поддерживает.

Проверка значения NULL

Если нужно проверить, является ли значение NULL, используйте:

В противном случае выражение с NULL никогда не будет истинным.

Фильтрация данных с помощью логических операторов

Следующие логические функции можно использовать вместе с предложением WHERE, чтобы объединять несколько условий:

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

В ClickHouse столбцы UInt8 можно напрямую использовать в качестве логических условий: 0 соответствует false, а любое ненулевое значение (обычно 1) — true. Пример приведён в разделе ниже.

Использование операторов сравнения

Можно использовать следующие операторы сравнения:

Оператор Функция Описание Пример
a = b equals(a, b) Равно price = 100
a == b equals(a, b) Равно (альтернативный синтаксис) price == 100
a != b notEquals(a, b) Не равно category != 'Electronics'
a <> b notEquals(a, b) Не равно (альтернативный синтаксис) category <> 'Electronics'
a < b less(a, b) Меньше price < 200
a <= b lessOrEquals(a, b) Меньше или равно price <= 200
a > b greater(a, b) Больше price > 500
a >= b greaterOrEquals(a, b) Больше или равно price >= 500
a LIKE s like(a, b) Сопоставление с шаблоном (с учетом регистра) name LIKE '%top%'
a NOT LIKE s notLike(a, b) Нет сопоставления с шаблоном (с учетом регистра) name NOT LIKE '%top%'
a ILIKE s ilike(a, b) Сопоставление с шаблоном (регистронезависимое) name ILIKE '%LAPTOP%'
a BETWEEN b AND c a >= b AND a <= c Проверка диапазона (включая границы) price BETWEEN 100 AND 500
a NOT BETWEEN b AND c a < b OR a > c Проверка нахождения вне диапазона price NOT BETWEEN 100 AND 500

Сопоставление с шаблоном и условные выражения

Помимо операторов сравнения, в предложении WHERE можно использовать сопоставление с шаблоном и условные выражения.

Возможность Синтаксис С учетом регистра Производительность Лучше всего подходит для
LIKE col LIKE '%pattern%' Да Быстро Сопоставления с шаблоном с учетом регистра
ILIKE col ILIKE '%pattern%' Нет Медленнее Регистронезависимого поиска
if() if(cond, a, b) Н/Д Быстро Простых бинарных условий
multiIf() multiIf(c1, r1, c2, r2, def) Н/Д Быстро Нескольких условий
CASE CASE WHEN ... THEN ... END Н/Д Быстро Условной логики в стандартном SQL

См. раздел "Сопоставление с шаблоном и условные выражения", чтобы посмотреть примеры использования.

Выражение с литералами, столбцами или подзапросами

Выражение после предложения WHERE также может включать литералы, столбцы или подзапросы — вложенные операторы SELECT, которые возвращают значения для использования в условиях.

Тип Определение Вычисление Производительность Пример
Литерал Фиксированное значение В момент записи запроса Самая высокая WHERE price > 100
Столбец Ссылка на данные таблицы Для каждой строки Высокая WHERE price > cost
Подзапрос Вложенный SELECT Во время выполнения запроса Зависит от случая WHERE id IN (SELECT ...)

Вы можете комбинировать литералы, столбцы и подзапросы в сложных условиях:

-- Literal + Column
WHERE price > 100 AND category = 'Electronics'

-- Column + Subquery
WHERE price > (SELECT AVG(price) FROM products) AND in_stock = true

-- Literal + Column + Subquery
WHERE category = 'Electronics'
  AND price < 500
  AND id IN (SELECT product_id FROM bestsellers)

-- All three with logical operators
WHERE (price > 100 OR category IN (SELECT category FROM featured))
  AND in_stock = true
  AND name LIKE '%Special%'

Примеры

Проверка значения NULL

Запросы со значениями NULL:

CREATE TABLE t_null(x Int8, y Nullable(Int8)) ENGINE=MergeTree() ORDER BY x;
INSERT INTO t_null VALUES (1, NULL), (2, 3);

SELECT * FROM t_null WHERE y IS NULL;
SELECT * FROM t_null WHERE y != 0;
┌─x─┬────y─┐
│ 1 │ ᴺᵁᴸᴸ │
└───┴──────┘
┌─x─┬─y─┐
│ 2 │ 3 │
└───┴───┘

Фильтрация данных с помощью логических операторов

Рассмотрим следующую таблицу и данные:

CREATE TABLE products (
    id UInt32,
    name String,
    price Float32,
    category String,
    in_stock Bool
) ENGINE = MergeTree()
ORDER BY id;

INSERT INTO products VALUES
(1, 'Laptop', 999.99, 'Electronics', true),
(2, 'Mouse', 25.50, 'Electronics', true),
(3, 'Desk', 299.00, 'Furniture', false),
(4, 'Chair', 150.00, 'Furniture', true),
(5, 'Monitor', 350.00, 'Electronics', true),
(6, 'Lamp', 45.00, 'Furniture', false);

1. AND — оба условия должны быть истинны:

SELECT * FROM products
WHERE category = 'Electronics' AND price < 500;
   ┌─id─┬─name────┬─price─┬─category────┬─in_stock─┐
1. │  2 │ Mouse   │  25.5 │ Electronics │ true     │
2. │  5 │ Monitor │   350 │ Electronics │ true     │
   └────┴─────────┴───────┴─────────────┴──────────┘

2. OR — хотя бы одно из условий должно выполняться:

SELECT * FROM products
WHERE category = 'Furniture' OR price > 500;
   ┌─id─┬─name───┬──price─┬─category────┬─in_stock─┐
1. │  1 │ Laptop │ 999.99 │ Electronics │ true     │
2. │  3 │ Desk   │    299 │ Furniture   │ false    │
3. │  4 │ Chair  │    150 │ Furniture   │ true     │
4. │  6 │ Lamp   │     45 │ Furniture   │ false    │
   └────┴────────┴────────┴─────────────┴──────────┘

3. NOT — отрицает условие:

SELECT * FROM products
WHERE NOT in_stock;
   ┌─id─┬─name─┬─price─┬─category──┬─in_stock─┐
1. │  3 │ Desk │   299 │ Furniture │ false    │
2. │  6 │ Lamp │    45 │ Furniture │ false    │
   └────┴──────┴───────┴───────────┴──────────┘

4. XOR — должно быть истинным ровно одно условие (но не оба сразу):

SELECT *
FROM products
WHERE xor(price > 200, category = 'Electronics')
   ┌─id─┬─name──┬─price─┬─category────┬─in_stock─┐
1. │  2 │ Mouse │  25.5 │ Electronics │ true     │
2. │  3 │ Desk  │   299 │ Furniture   │ false    │
   └────┴───────┴───────┴─────────────┴──────────┘

5. Объединение нескольких операторов:

SELECT * FROM products
WHERE (category = 'Electronics' OR category = 'Furniture')
  AND in_stock = true
  AND price < 400;
   ┌─id─┬─name────┬─price─┬─category────┬─in_stock─┐
1. │  2 │ Mouse   │  25.5 │ Electronics │ true     │
2. │  4 │ Chair   │   150 │ Furniture   │ true     │
3. │  5 │ Monitor │   350 │ Electronics │ true     │
   └────┴─────────┴───────┴─────────────┴──────────┘

6. Использование синтаксиса функции:

SELECT * FROM products
WHERE and(or(category = 'Electronics', price > 100), in_stock);
   ┌─id─┬─name────┬──price─┬─category────┬─in_stock─┐
1. │  1 │ Laptop  │ 999.99 │ Electronics │ true     │
2. │  2 │ Mouse   │   25.5 │ Electronics │ true     │
3. │  4 │ Chair   │    150 │ Furniture   │ true     │
4. │  5 │ Monitor │    350 │ Electronics │ true     │
   └────┴─────────┴────────┴─────────────┴──────────┘

Синтаксис с ключевыми словами SQL (AND, OR, NOT, XOR) обычно более удобочитаем, но синтаксис функций может быть полезен в сложных выражениях или при построении динамических запросов.

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

Используя таблицу из предыдущего примера, можно использовать имя столбца непосредственно в качестве условия:

SELECT * FROM products
WHERE in_stock
   ┌─id─┬─name────┬──price─┬─category────┬─in_stock─┐
1. │  1 │ Laptop  │ 999.99 │ Electronics │ true     │
2. │  2 │ Mouse   │   25.5 │ Electronics │ true     │
3. │  4 │ Chair   │    150 │ Furniture   │ true     │
4. │  5 │ Monitor │    350 │ Electronics │ true     │
   └────┴─────────┴────────┴─────────────┴──────────┘

Использование операторов сравнения

В примерах ниже используются таблица и данные из примера выше. Результаты для краткости не приводятся.

1. Явная проверка на равенство с true (= 1 или = true):

SELECT * FROM products
WHERE in_stock = true;
-- или
WHERE in_stock = 1;

2. Явная проверка на равенство false (= 0 or = false):

SELECT * FROM products
WHERE in_stock = false;
-- или
WHERE in_stock = 0;

3. Условие неравенства (!= 0 или != false):

SELECT * FROM products
WHERE in_stock != false;
-- или
WHERE in_stock != 0;

4. Больше:

SELECT * FROM products
WHERE in_stock > 0;

5. Меньше или равно:

SELECT * FROM products
WHERE in_stock <= 0;

6. Комбинирование с другими условиями:

SELECT * FROM products
WHERE in_stock AND price < 400;

7. Использование оператора IN:

В примере ниже (1, true)кортеж.

SELECT * FROM products
WHERE in_stock IN (1, true);

Для этого также можно использовать массив:

SELECT * FROM products
WHERE in_stock IN [1, true];

8. Смешение стилей сравнения:

SELECT * FROM products
WHERE category = 'Electronics' AND in_stock = true;

Сопоставление с шаблоном и условные выражения

В примерах ниже используются таблица и данные из примера, приведённого выше. Результаты опущены для краткости.

Примеры LIKE

-- Найти продукты с 'o' в названии
SELECT * FROM products WHERE name LIKE '%o%';
-- Результат: Laptop, Monitor

-- Найти продукты, начинающиеся с 'L'
SELECT * FROM products WHERE name LIKE 'L%';
-- Результат: Laptop, Lamp

-- Найти продукты, содержащие ровно 4 символа в названии
SELECT * FROM products WHERE name LIKE '____';
-- Результат: Desk, Lamp

Примеры ILIKE

-- Регистронезависимый поиск по 'LAPTOP'
SELECT * FROM products WHERE name ILIKE '%laptop%';
-- Результат: Laptop

-- Регистронезависимое совпадение по префиксу
SELECT * FROM products WHERE name ILIKE 'l%';
-- Результат: Laptop, Lamp

Примеры функции IF

-- Различные пороговые значения цен по категориям
SELECT * FROM products
WHERE if(category = 'Electronics', price < 500, price < 200);
-- Результат: Mouse, Chair, Monitor
-- (Electronics дешевле $500 ИЛИ Furniture дешевле $200)

-- Фильтрация по статусу наличия на складе
SELECT * FROM products
WHERE if(in_stock, price > 100, true);
-- Результат: Laptop, Chair, Monitor, Desk, Lamp
-- (Товары в наличии дороже $100 ИЛИ все товары не в наличии)

Примеры multiIf

-- Несколько условий на основе категорий
SELECT * FROM products
WHERE multiIf(
    category = 'Electronics', price < 600,
    category = 'Furniture', in_stock = true,
    false
);
-- Результат: Mouse, Monitor, Chair
-- (Electronics < $600 ИЛИ Furniture в наличии)

-- Многоуровневая фильтрация
SELECT * FROM products
WHERE multiIf(
    price > 500, category = 'Electronics',
    price > 100, in_stock = true,
    true
);
-- Результат: Laptop, Chair, Monitor, Lamp

Примеры CASE

Простой CASE:

-- Different rules per category
SELECT * FROM products
WHERE CASE category
    WHEN 'Electronics' THEN price < 400
    WHEN 'Furniture' THEN in_stock = true
    ELSE false
END;
-- Result: Mouse, Monitor, Chair

Поисковый CASE:

-- Price-based tiered logic
SELECT * FROM products
WHERE CASE
    WHEN price > 500 THEN in_stock = true
    WHEN price > 100 THEN category = 'Electronics'
    ELSE true
END;
-- Result: Laptop, Monitor, Mouse, Lamp
Navigation