DBAtlas · Атлас эксплуатации баз данных

WITH (Common Table Expression / CTE)

Oracle

WITH region AS (
  SELECT city, COUNT(*) AS n
  FROM customer
  GROUP BY city
)
SELECT city, n FROM region WHERE n > 10;

WITH определяет именованный временный набор результатов (CTE) внутри запроса; вместо многократного написания подзапроса вы определяете его один раз и ссылаетесь по имени. Разбивает сложные запросы на читаемые части. Поддерживается с Oracle 9i.

PostgreSQL

WITH region AS (
  SELECT city, COUNT(*) AS n
  FROM customer
  GROUP BY city
)
SELECT city, n FROM region WHERE n > 10;

CTE разбивает сложные запросы на именованные блоки. До PostgreSQL 12 CTE был барьером оптимизации (всегда материализовался); начиная с 12 он может встраиваться, а старое поведение задаётся принудительно через WITH ... AS MATERIALIZED.

MySQL

WITH region AS (
  SELECT city, COUNT(*) AS n
  FROM customer
  GROUP BY city
)
SELECT city, n FROM region WHERE n > 10;

CTE определяет временный именованный набор результатов в запросе и улучшает читаемость. Поддерживается с MySQL 8.0 (и MariaDB 10.2); старым версиям нужна производная таблица (подзапрос в FROM).

SQL Server

WITH region AS (
  SELECT city, COUNT(*) AS n
  FROM customer
  GROUP BY city
)
SELECT city, n FROM region WHERE n > 10;

CTE — именованный временный набор результатов. В SQL Server оператор непосредственно перед CTE должен заканчиваться точкой с запятой, поэтому WITH часто пишут как ';WITH'. Действует в пределах одного оператора (SELECT/INSERT/UPDATE/DELETE).

MongoDB

// Closest equivalent: aggregation pipeline stages
db.customer.aggregate([
  { $group: { _id: "$city", n: { $sum: 1 } } },
  { $match: { n: { $gt: 10 } } }
])

В MongoDB нет SQL/CTE; ту же задачу решают этапы конвейера агрегации. Каждый этап принимает вывод предыдущего, что даёт пошаговую обработку, похожую на цепочки CTE. Для промежуточных результатов можно также использовать $facet или $lookup.

Redis

# Not applicable: Redis has no concept of SQL or CTEs.

Redis — хранилище ключ-значение без языка запросов. Промежуточные результаты объединяйте на стороне клиента или используйте Lua-скрипт (EVAL) для серверной логики.

Elasticsearch

# CTEs are not supported in Elasticsearch SQL.
POST _sql
{ "query": "SELECT city, COUNT(*) n FROM customer GROUP BY city HAVING COUNT(*) > 10" }

Elasticsearch SQL (API _sql) не поддерживает синтаксис WITH/CTE; группировка и фильтрация пишутся в одном SELECT. При нативном подходе то же делается агрегацией 'terms' и pipeline-агрегацией 'bucket_selector'.

Открыть в DBAtlas →