Это кусок SQL, который ты задаёшь через WITH ... AS (...) и потом используешь в основном запросе.

WITH numbers AS (
    SELECT 1 AS n
    UNION ALL
    SELECT 2
    UNION ALL
    SELECT 3
)
SELECT n * 10
FROM numbers;

Здесь numbers — это CTE. Оно не сохраняется в базе, не индексируется и живёт только в рамках одного запроса.

Как работает в PostgreSQL

  • До версии 12: CTE всегда материализовались — т.е. результат вычислялся, складывался во временный tuplestore (в памяти или на диск), и потом из него читали. Оптимизатор внутрь не заглядывал. Это гарантировало независимость, но иногда тормозило.
  • С версии 12: по умолчанию CTE инлайнится как подзапрос, если только не указано MATERIALIZED. Это значит, что PostgreSQL может переписывать и оптимизировать его вместе с основным запросом.

database