WITH
Задаёт именованный подзапрос (общее табличное выражение, CTE), к которому основной запрос обращается как к таблице.
WITH [RECURSIVE] name_cte [(column[, ...])] AS (subquery) main_query- [ ]необязательная часть
- ...можно повторить
- RECURSIVE
- Разрешает табличному выражению ссылаться на само себяКлючевое словоНеобязательный
- name_cte
- Имя табличного выраженияИмя
- column
- Имена столбцов табличного выражения, по умолчанию берутся из subqueryИмяНеобязательный
- subquery
- Подзапрос, результат которого доступен по имени name_cteПодзапрос
- main_query
- Основной запрос, который обращается к name_cte как к таблицеПодзапрос
Возвращаемое значение
Временная именованная выборка, доступная только в этом запросе
Примеры
Число рейсов каждой компании
WITH company_trips AS (
SELECT company,
COUNT(*) AS trips
FROM Trip
GROUP BY company
)
SELECT Company.name,
company_trips.trips
FROM company_trips
JOIN Company ON Company.id = company_trips.company
ORDER BY company_trips.trips DESC;Числа от 1 до 5 через RECURSIVE
WITH RECURSIVE numbers (n) AS (
SELECT 1
UNION ALL
SELECT n + 1
FROM numbers
WHERE n < 5
)
SELECT n
FROM numbers;Строка растёт в рекурсии
WITH RECURSIVE stars (n, line) AS (
SELECT 1,
CAST('*' AS CHAR(10))
UNION ALL
SELECT n + 1,
CONCAT(line, '*')
FROM stars
WHERE n < 5
)
SELECT n,
line
FROM stars;Подробности
После одного WITH можно перечислить через запятую несколько табличных выражений, и каждое может ссылаться на предыдущие.
Рекурсивное выражение состоит из начального запроса и рекурсивной части, соединённых через UNION ALL или UNION (он ещё убирает повторы), и должно содержать условие остановки. По умолчанию рекурсивная часть выполняется не больше 1000 раз (переменная cte_max_recursion_depth), дальше запрос завершается ошибкой.
Типы столбцов задаёт начальный запрос. Если рекурсивная часть удлиняет строку, начальное значение нужно расширить заранее: CAST('*' AS CHAR(10)), иначе будет ошибка «Data too long».