{#where-where} # WHERE {bdg-primary-line}`GQL 절` 패턴을 제약하거나 투영을 걸러 냅니다. 조건이 참이 아닌 행은 버려집니다. {#where-synopsis} ## 개요
WHERE condition

굵게 키워드 · 기울임 직접 채우는 자리 · [ ] 생략 가능 · ... 반복 가능. 구문 표기 규약을 참고하십시오.

{#where-description} ## 설명 `WHERE`는 그 자체로 절이 아닙니다. 세 절 중 하나에 붙고, 붙은 절에서 뜻을 얻습니다: - [`MATCH`](match.md)에 붙으면 그 일치의 일부입니다. 조건이 실행될 때 패턴의 모든 변수가 바인딩돼 있고, 조건에서 걸린 일치는 만들어지지 않습니다. - [`OPTIONAL MATCH`](optional-match.md)에 붙으면 그 선택적 일치의 일부입니다. 조건에서 걸린 행은 패턴의 변수가 null인 채로 **남습니다.** - [`WITH`](with.md)에 붙으면 집계가 끝난 뒤 투영된 행을 걸러 냅니다. 집계에 대한 조건이 놓이는 자리가 여기입니다. 조건은 불리언 표현식이어야 합니다. 다른 타입의 값은 강제 변환되지 않습니다. 조건에 놓인 jsonb 문자열이나 숫자는 참으로 취급되는 것이 아니라 오류를 냅니다. `WHERE`에는 집계 함수를 쓸 수 없습니다. 그것은 `WITH`에 넣고 그 결과를 걸러 내십시오. `WHERE`만 쓰는 것은 구문 오류이고, 쿼리가 그것으로 끝날 수도 없습니다. 홀로 서고 이어 쓸 수 있는 필터는 [`FILTER`](filter.md)이며, `FILTER condition`과 `FILTER WHERE condition` 둘 다 받습니다. {#where-parameters} ## 매개변수 condition : 불리언 타입의 표현식입니다. 여러 검사는 `AND`, `OR`, `XOR`, `NOT`으로 엮으십시오. {#where-examples} ## 예제 모든 예제는 [예제 데이터셋](../../get_started/example-dataset.md)에서 실행됩니다. {#where-compare-a-property} ### 속성 비교하기 ```cypher MATCH (m:movie) WHERE m.year > 2015 RETURN m.title AS film, m.year AS year ORDER BY year, film; ``` ``` film | year ----------------------------+------ "Blade Runner 2049" | 2017 "The Matrix Resurrections" | 2021 (2 rows) ``` {#where-combine-conditions} ### 조건 엮기 ```cypher MATCH (m:movie) WHERE m.genre = 'Action' AND m.year < 1995 RETURN m.title AS film ORDER BY film; ``` ``` film ------------------------------ "Terminator 2: Judgment Day" "The Terminator" (2 rows) ``` `AND`, `OR`, `NOT`과 함께 `XOR`도 쓸 수 있습니다: ```cypher MATCH (m:movie) WHERE m.genre = 'Action' XOR m.year < 1995 RETURN count(*) AS n; ``` ``` n --- 8 (1 row) ``` {#where-test-a-label} ### 레이블 검사하기 `label()`은 요소의 레이블을 문자열로 반환하며, 정점과 간선 모두 마찬가지입니다: ```cypher MATCH (n) WHERE label(n) = 'person' RETURN count(*) AS n; ``` ``` n ---- 28 (1 row) ``` 이름 목록에 대한 `IN`이, 간선 패턴으로는 표현할 수 없는 「여러 간선 레이블에 일치시키기」를 하는 방법입니다: ```cypher MATCH (p:person)-[r]->(m:movie) WHERE label(r) IN ['acted_in', 'directed'] RETURN count(r) AS edges; ``` ``` edges ------- 46 (1 row) ``` {#where-match-on-a-substring-or-a-pattern} ### 부분 문자열이나 패턴으로 일치시키기 `STARTS WITH`, `ENDS WITH`, `CONTAINS`는 문자열 속성을 검사합니다: ```cypher MATCH (m:movie) WHERE m.title STARTS WITH 'The Matrix' RETURN count(*) AS n; ``` ``` n --- 4 (1 row) ``` ```cypher MATCH (m:movie) WHERE m.title ENDS WITH 'Runner' RETURN m.title AS film; ``` ``` film ---------------- "Blade Runner" (1 row) ``` `=~`는 POSIX 정규 표현식으로 일치시킵니다: ```cypher MATCH (m:movie) WHERE m.title =~ '^Blade.*' RETURN m.title AS film ORDER BY film; ``` ``` film --------------------- "Blade Runner" "Blade Runner 2049" (2 rows) ``` 부정은 `NOT`으로 하십시오. 속성에 쓰는 `!~`도, `NOT LIKE`도 없습니다: ```cypher MATCH (m:movie) WHERE NOT m.title STARTS WITH 'The' RETURN count(*) AS n; ``` ``` n ---- 11 (1 row) ``` {#where-test-for-a-missing-property} ### 없는 속성 검사하기 설정된 적 없는 속성은 null로 읽히므로, 그것이 없는지 검사하는 것이 `IS NULL`입니다: ```cypher MATCH (m:movie) WHERE m.runtime IS NULL RETURN count(*) AS n; ``` ``` n ---- 18 (1 row) ``` {#where-test-for-a-pattern} ### 패턴 검사하기 서브쿼리 표현식은 패턴에서 아무것도 바인딩하지 않고 그 패턴이 존재하는지 검사합니다: ```cypher MATCH (p:person) WHERE EXISTS { MATCH (p)-[:directed]->() } RETURN p.name AS director ORDER BY director LIMIT 4; ``` ``` director --------------------- "Andrew Niccol" "Christopher Nolan" "Denis Villeneuve" "James Cameron" (4 rows) ``` {#where-filter-an-aggregate-with-with} ### WITH로 집계를 걸러 내기 `WHERE` 안의 집계 함수는 거부됩니다: ```cypher MATCH (p:person)-[:acted_in]->(m:movie) WHERE count(m) > 1 RETURN p.name; ``` ``` ERROR: aggregate functions are not allowed in WHERE ``` `WITH`에서 집계하고, 그다음 그 결과를 걸러 내십시오. `WITH` 절 자신의 `WHERE`는 그룹화 뒤에 실행됩니다: ```cypher MATCH (p:person)-[:acted_in]->(m:movie) WITH p, count(m) AS films WHERE films >= 3 RETURN p.name AS actor, films ORDER BY actor; ``` ``` actor | films -------------------------+------- "Arnold Schwarzenegger" | 3 "Keanu Reeves" | 4 (2 rows) ``` {#where-notes} ## 참고 속성은 jsonb 값을 담고 있고, 그것을 리터럴과 비교하는 것은 jsonb 값끼리의 비교입니다. jsonb 순서에서 숫자는 모든 문자열보다 위에 오므로, 따옴표로 감싼 숫자를 수치 속성과 비교하면 뜻한 비교가 되지 않습니다: ```cypher MATCH (m:movie {title: 'The Matrix'}) RETURN m.year > '9999' AS num_gt_str, m.year > 1990 AS num_gt_num; ``` ``` num_gt_str | num_gt_num ------------+------------ t | t (1 row) ``` 저장된 타입이 예상과 다르다면, 리터럴을 그 속성의 타입으로 쓰거나 `m.year::int > 1990`처럼 속성을 형 변환하십시오. ```{note} `WHERE`는 불리언만 받습니다. `WHERE m.title`은 `cannot cast "The Matrix" (jsonb type string) to boolean`을 냅니다. 참·거짓을 느슨하게 보는 언어라면 빈 문자열이 아닌 것을 참으로 취급할 자리입니다. 명시적으로 비교하거나 `IS NOT NULL`을 쓰십시오. ``` {#where-compatibility} ## 호환성 {#where-labeled-predicate-isoiec-39075-199} ### 레이블 술어 (ISO/IEC 39075 §19.9) 표준은 레이블 검사를 `n IS LABELED movie`로 쓰고 `n:movie`를 축약형으로 둡니다. AgensGraph는 둘 다 받지 않습니다. `label(n) = 'movie'`를 쓰십시오. {#where-pattern-predicates} ### 패턴 술어 패턴만 쓴 것은 표현식이 아니므로 조건으로 쓸 수 없습니다. `WHERE (m)-[:related_to]->(:movie)`는 구문 오류이고, 레이블 없는 `WHERE (m)-[]->()`도 그렇습니다. 표준이 §19.4에 정의하고 AgensGraph가 지원하는 `EXISTS { MATCH ... }`로 감싸십시오. {#where-sql-string-operators} ### SQL의 문자열 연산자 `LIKE`와 `NOT LIKE`는 Cypher 조건의 일부가 아닙니다. `WHERE m.title LIKE 'Blade%'`는 형 변환을 붙이든 붙이지 않든 구문 오류입니다. `STARTS WITH`, `ENDS WITH`, `CONTAINS`, `=~`를 쓰십시오. SQL 연산자를 쓰려면 Cypher를 SQL로 감싸십시오. [SQL과 Cypher 섞기](../../querying/combining-sql-and-cypher.md)를 참고하십시오. {#where-see-also} ## 관련 항목 - [`MATCH`](match.md) — `WHERE`가 가장 자주 붙는 절 - [`OPTIONAL MATCH`](optional-match.md) — 조건에서 걸린 행이 남는 자리 - [`WITH`](with.md) — 투영이나 집계 뒤에 걸러 내기 - [`FILTER`](filter.md) — 홀로 서는 필터 절 - [서브쿼리 표현식](subquery-expressions.md) — `EXISTS`, `COUNT`, `COLLECT` 등