Использование CTE¶
Предложение WITH добавляется перед DQL-командой
SELECT и позволяет использовать в запросе временные
таблицы.
Такие временные таблицы называются общими табличными выражениями (англ. CTE — common table expressions) и существуют только в контексте выполнения запроса.
Предложение WITH агрессивно материализует результаты в памяти и почти
никогда не использует встраивание подзапроса в синтаксическое дерево
команды SELECT.
В область видимости общих табличных выражений и команды SELECT попадают
результаты выражений, описанных ранее в запросе WITH. Например, есть
запрос WITH с тремя общими табличными выражениями:
WITH
<cte1>,
<cte2>,
<cte3>
SELECT <...>
В команде SELECT можно использовать результаты выражений <cte1>,
<cte2>, <cte3>. В выражении <cte3> — результаты выражений <cte1>,
<cte2>. В выражении <cte2> — результат выражения <cte1>. В выражении
<cte1> должны использоваться запросы к уже существующим таблицам.
Синтаксис¶
Параметры¶
- cte — имя общего табличного выражения. Соответствует правилам имен для всех объектов в кластере
- column — имя колонки общего табличного выражения. Соответствует правилам имен для всех объектов в кластере
Примеры¶
Тестовые таблицы
Примеры использования команд включают в себя запросы к тестовым таблицам.
WITH replenish (item, amount)
AS (SELECT item, amount FROM orders WHERE amount <= 1000)
SELECT item, amount FROM replenish;
Результат:
+-------------+--------+
| item | amount |
+======================+
| "adhesives" | 350 |
|-------------+--------|
| "moldings" | 900 |
|-------------+--------|
| "bars" | 100 |
+-------------+--------+
(3 rows)
WITH leftovers (item, orders_data, deliveries_data) AS (
SELECT item, amount, deliveries.quantity
FROM orders
JOIN deliveries
ON item = deliveries.product
)
SELECT item, orders_data - deliveries_data AS amount FROM leftovers;
Результат:
+-------------+--------+
| item | amount |
+======================+
| "metalware" | 3000 |
|-------------+--------|
| "adhesives" | 50 |
|-------------+--------|
| "moldings" | 800 |
|-------------+--------|
| "bars" | 95 |
|-------------+--------|
| "blocks" | 5000 |
+-------------+--------+
(5 rows)
WITH
c (total) AS (SELECT count(*) FROM orders),
m (earliest_date) AS (SELECT min(since) FROM orders)
SELECT c.total, m.earliest_date FROM c LEFT JOIN m ON true;
Результат:
+-------+------------------------+
| total | earliest_date |
+================================+
| 5 | "2023-11-11T00:00:00Z" |
+-------+------------------------+
(1 rows)
WITH
ordered_items (id, name, stock) AS (
SELECT items.* FROM items
JOIN orders
ON items.name = orders.item
),
total_stock (total) AS (
SELECT sum(stock) FROM ordered_items
)
SELECT * FROM total_stock;
Результат:
+-------+
| total |
+=======+
| 90227 |
+-------+
(1 rows)