본문으로 바로가기
본문으로 바로가기

WHERE 절

WHERE 절은 SELECTFROM 절에서 가져온 데이터를 필터링하는 데 사용합니다.

WHERE 절이 있는 경우, 그 뒤에는 UInt8 타입의 표현식이 와야 합니다. 이 표현식이 0으로 평가되는 행은 이후 변환이나 최종 결과에서 제외됩니다.

WHERE 절 뒤의 표현식은 종종 비교 연산자논리 연산자, 또는 다양한 일반 함수 중 하나와 함께 사용됩니다.

WHERE 절의 표현식은, 사용하는 테이블 엔진이 이를 지원하는 경우 인덱스 사용 및 파티션 프루닝(partition pruning)에 활용될 수 있는지 평가됩니다.

PREWHERE

PREWHERE라고 하는 필터링 최적화 기능도 있습니다. Prewhere는 필터링을 더 효율적으로 적용하기 위한 최적화 기능입니다. PREWHERE 절을 명시적으로 지정하지 않더라도 기본적으로 활성화되어 있습니다.

NULL 테스트

값이 NULL인지 확인해야 하는 경우 다음을 사용합니다:

그 밖의 NULL이 포함된 표현식은 조건을 통과하지 않습니다.

논리 연산자로 데이터 필터링

다음 논리 함수WHERE 절과 함께 사용하여 여러 조건을 결합할 수 있습니다:

조건으로 UInt8 컬럼 사용하기

ClickHouse에서는 UInt8 컬럼을 불리언 조건으로 직접 사용할 수 있으며, 0false, 0이 아닌 값(일반적으로 1)은 true로 간주됩니다. 관련 예시는 아래 섹션에 나와 있습니다.

비교 연산자 사용

다음 비교 연산자를 사용할 수 있습니다.

OperatorFunctionDescriptionExample
a = bequals(a, b)같음price = 100
a == bequals(a, b)같음 (대체 구문)price == 100
a != bnotEquals(a, b)같지 않음category != 'Electronics'
a <> bnotEquals(a, b)같지 않음 (대체 구문)category <> 'Electronics'
a < bless(a, b)보다 작음price < 200
a <= blessOrEquals(a, b)작거나 같음price <= 200
a > bgreater(a, b)보다 큼price > 500
a >= bgreaterOrEquals(a, b)크거나 같음price >= 500
a LIKE slike(a, b)패턴 일치 (대소문자 구분)name LIKE '%top%'
a NOT LIKE snotLike(a, b)패턴 불일치 (대소문자 구분)name NOT LIKE '%top%'
a ILIKE silike(a, b)패턴 일치 (대소문자 구분 안 함)name ILIKE '%LAPTOP%'
a BETWEEN b AND ca >= b AND a <= c구간 검사 (경계값 포함)price BETWEEN 100 AND 500
a NOT BETWEEN b AND ca < b OR a > c구간 외 검사price NOT BETWEEN 100 AND 500

패턴 일치와 조건식

비교 연산자 외에도 WHERE 절에서 패턴 일치와 조건식을 사용할 수 있습니다.

기능구문대소문자 구분성능적합한 용도
LIKEcol LIKE '%pattern%'Fast대소문자를 구분하는 패턴 일치
ILIKEcol ILIKE '%pattern%'아니요Slower대소문자를 구분하지 않는 검색
if()if(cond, a, b)해당 없음Fast단순한 이분 조건
multiIf()multiIf(c1, r1, c2, r2, def)해당 없음Fast다중 조건
CASECASE WHEN ... THEN ... END해당 없음FastSQL 표준 조건식

See "Pattern matching and conditional expressions" for usage examples.

리터럴, 컬럼 또는 서브쿼리를 사용하는 표현식

WHERE 절 뒤에 오는 표현식에는 리터럴, 컬럼 또는 서브쿼리를 포함할 수 있습니다. 서브쿼리는 조건식에서 사용되는 값을 반환하는 중첩된 SELECT 문입니다.

TypeDefinitionEvaluationPerformanceExample
Literal고정 상수 값쿼리 작성 시점가장 빠름WHERE price > 100
Column테이블 데이터 참조행마다빠름WHERE price > cost
Subquery중첩된 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)

-- 세 조건 모두에 논리 연산자 사용 WHERE (price > 100 OR category IN (SELECT category FROM featured)) AND in_stock = true AND name LIKE '%Special%'

## Examples            

### Testing for `NULL`                             

Queries with `NULL` values:

```sql
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     │
   └────┴─────────┴────────┴─────────────┴──────────┘

AND, OR, NOT, XOR와 같은 SQL 키워드 구문이 일반적으로 더 읽기 쉽지만, 함수 구문은 복잡한 표현식이나 동적 쿼리를 작성할 때 유용할 수 있습니다.

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;
-- or
WHERE in_stock = 1;

2. false와의 명시적 동등 비교 (= 0 또는 = false):

SELECT * FROM products
WHERE in_stock = false;
-- or
WHERE in_stock = 0;

3. 같지 않음 (!= 0 또는 != false):

SELECT * FROM products
WHERE in_stock != false;
-- or
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);

이 작업에는 array를 사용할 수도 있습니다:

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

8. 비교 스타일 혼용:

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

패턴 일치와 조건식

아래 예제에서는 위 예시의 테이블과 데이터를 사용합니다. 예제 결과는 간단히 하기 위해 생략합니다.

LIKE 예시

-- Find products with 'o' in the name
SELECT * FROM products WHERE name LIKE '%o%';
-- Result: Laptop, Monitor

-- Find products starting with 'L'
SELECT * FROM products WHERE name LIKE 'L%';
-- Result: Laptop, Lamp

-- Find products with exactly 4 characters
SELECT * FROM products WHERE name LIKE '____';
-- Result: Desk, Lamp

ILIKE 사용 예시

-- Case-insensitive search for 'LAPTOP'
SELECT * FROM products WHERE name ILIKE '%laptop%';
-- Result: Laptop

-- Case-insensitive prefix match
SELECT * FROM products WHERE name ILIKE 'l%';
-- Result: Laptop, Lamp

IF 예제

-- Different price thresholds by category
SELECT * FROM products
WHERE if(category = 'Electronics', price < 500, price < 200);
-- Result: Mouse, Chair, Monitor
-- (Electronics under $500 OR Furniture under $200)

-- Filter based on stock status
SELECT * FROM products
WHERE if(in_stock, price > 100, true);
-- Result: Laptop, Chair, Monitor, Desk, Lamp
-- (In stock items over $100 OR all out-of-stock items)

multiIf 예시

-- Multiple category-based conditions
SELECT * FROM products
WHERE multiIf(
    category = 'Electronics', price < 600,
    category = 'Furniture', in_stock = true,
    false
);
-- Result: Mouse, Monitor, Chair
-- (Electronics < $600 OR in-stock Furniture)

-- Tiered filtering
SELECT * FROM products
WHERE multiIf(
    price > 500, category = 'Electronics',
    price > 100, in_stock = true,
    true
);
-- Result: 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