공통 테이블 표현식
SELECT 쿼리라면 어느 위치에서든 이름으로 참조할 수 있습니다.
이름이 있는 서브쿼리는 현재 쿼리의 범위 내에서, 또는 하위 서브쿼리의 범위 내에서 이름으로 참조할 수 있습니다.
SELECT 쿼리에서 공통 테이블 표현식에 대한 모든 참조는 CTE가 명시적으로 구체화된 것으로 정의되지 않은 한(Materialized Common Table Expressions 참조), 항상 해당 정의의 서브쿼리로 대체됩니다.
재귀는 현재 CTE를 식별자 해석 과정에서 숨겨 방지합니다.
CTE는 호출되는 모든 위치에서 동일한 결과를 보장하지 않는다는 점에 유의하십시오. 사용될 때마다 쿼리가 다시 실행되기 때문입니다.
구문
예시
1000000이 표시됩니다.
하지만 cte_numbers를 두 번 참조하기 때문에 매번 난수가 생성되고, 그 결과 280501, 392454, 261636, 196227 등 서로 다른 값이 표시됩니다…
구체화된 공통 테이블 표현식
MATERIALIZED 키워드를 추가하면 ClickHouse는 CTE 서브쿼리를 정확히 한 번만 실행하고, 그 결과를 임시 테이블에 저장한 다음, 모든 참조가 해당 테이블에서 결과를 가져오도록 합니다.
따라서 동일한 CTE가 하나의 쿼리에서 여러 번 참조되는 경우(예: self-join 또는 여러 IN 서브쿼리) 특히 유용합니다. 기본 계산은 한 번만 수행되기 때문입니다.
구체화된 CTE는 실험적 기능입니다.
사용하려면 분석기와 설정
enable_materialized_cte가 활성화되어 있어야 합니다.구문
사용하면 좋은 경우
- 하나의 쿼리에서 동일한 CTE를 두 번 이상 참조하는 경우입니다.
MATERIALIZED를 사용하지 않으면 각 참조마다 서브쿼리가 독립적으로 다시 실행됩니다. - CTE에
generateRandom과 같은 비결정적 함수가 포함된 경우입니다. 구체화하면 모든 참조에서 동일한 데이터를 보게 됩니다. - CTE에 비용이 큰 계산(집계, 조인, 대규모 스캔)이 포함되어 있어 반복 실행을 피해야 하는 경우입니다.
예시
MATERIALIZED가 없으면 조인의 양쪽에서 각각 서브쿼리를 독립적으로 실행합니다.
MATERIALIZED를 사용하면 테이블을 한 번만 스캔하고, 조인의 양쪽이 동일한 임시 테이블에서 읽습니다.
generateRandom을 사용하면 참조할 때마다 서로 다른 결과가 생성됩니다.
CTE를 구체화하면 일관성이 보장됩니다:
1000000입니다.
예시 3: 구체화된 CTE 연결하기
구체화된 CTE는 다른 구체화된 CTE를 참조할 수 있습니다.
ClickHouse는 종속성을 해결하고 올바른 순서로 구체화합니다.
제약 사항
- 실험적 설정 필요:
enable_materialized_cte설정을 활성화해야 합니다. - 분석기 필요: 구체화된 CTE는 분석기가 활성화된 경우에만 작동합니다(
enable_analyzer = 1). RECURSIVE와 함께 사용할 수 없음:MATERIALIZED와RECURSIVE키워드를 함께 사용하는 것은 허용되지 않으며,UNSUPPORTED_METHOD예외가 발생합니다.- 상관 CTE 사용 금지: 구체화된 CTE는 외부 쿼리 범위의 컬럼을 참조할 수 없습니다.
공통 스칼라 표현식
WITH 절에서 임의의 스칼라 표현식에 대한 별칭을 선언할 수 있습니다.
공통 스칼라 표현식은 쿼리의 어느 위치에서나 참조할 수 있습니다.
구문
예시
extension은 gen_name 람다 함수 본문에서 바인딩되어 있지 않습니다.
extension은 generated_names의 정의 및 사용 스코프에서 공통 스칼라 표현식으로 '.txt'로 정의되어 있지만, generated_names 서브쿼리(subquery)에서 사용할 수 있으므로 테이블 extension_list의 컬럼(column)으로 해석됩니다.
재귀 쿼리
RECURSIVE 수정자를 사용하면 WITH 쿼리가 자신의 출력 결과를 참조할 수 있습니다. 예시:
예시: 1부터 100까지 정수의 합
재귀 CTE는 버전 **
24.3**에 도입된 쿼리 분석기에 의존합니다. 24.3+ 버전을 사용 중인데 (UNKNOWN_TABLE) 또는 (UNSUPPORTED_METHOD) 예외가 발생한다면, 인스턴스, role 또는 profile에서 분석기가 비활성화되어 있음을 의미합니다. 분석기를 활성화하려면 allow_experimental_analyzer 설정을 켜거나 compatibility 설정을 더 최신 버전으로 업데이트하십시오.
24.8 버전부터 분석기는 완전히 정식 기능으로 승격되었으며, allow_experimental_analyzer 설정 이름은 enable_analyzer로 변경되었습니다.WITH 쿼리의 일반적인 형태는 항상 비재귀 항, 그다음 UNION ALL, 그다음 재귀 항으로 이루어집니다. 이때 쿼리 자신의 출력에 대한 참조를 포함할 수 있는 것은 재귀 항뿐입니다. 재귀 CTE 쿼리는 다음과 같이 실행됩니다:
- 비재귀 항을 평가합니다. 비재귀 항 쿼리의 결과를 임시 작업 테이블에 저장합니다.
- 작업 테이블이 비어 있지 않은 동안 다음 단계를 반복합니다:
- 재귀 항을 평가하면서, 재귀 자기 참조를 작업 테이블의 현재 내용으로 치환합니다. 재귀 항 쿼리의 결과를 임시 중간 테이블에 저장합니다.
- 작업 테이블의 내용을 중간 테이블의 내용으로 대체한 다음, 중간 테이블을 비웁니다.
탐색 순서
사이클 감지
Maximum recursive CTE evaluation depth 오류로 실패합니다:
무한 쿼리
LIMIT를 사용하면 무한 재귀 CTE 쿼리도 사용할 수 있습니다:
예시: 무한 재귀 CTE 쿼리
후행 쉼표
WITH 절의 마지막 요소 뒤에도 쉼표를 사용할 수 있습니다: