Предложение WHERE позволяет фильтровать данные, поступающие из предложения FROM оператора SELECT.
Если есть предложение WHERE, за ним должно следовать выражение типа UInt8.
Строки, для которых это выражение вычисляется в 0, исключаются из дальнейших преобразований или из результата.
Выражение после предложения WHERE часто используется с операторами сравнения и логическими операторами, а также с одной из множества обычных функций.
При вычислении выражения WHERE могут использоваться индексы и отсечение партиций, если базовый движок таблицы это поддерживает.
Проверка значения NULL
Если нужно проверить, является ли значение NULL, используйте:
IS NULLилиisNullIS NOT NULLилиisNotNull
В противном случае выражение с 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