Я никогда не использую CTE с рекурсией. Я как раз читал об этом статью. В этой статье показана информация о сотрудниках с помощью CTE и рекурсии сервера Sql. В основном это показывает информацию о сотрудниках и их менеджерах. Я не могу понять, как работает этот запрос. Вот запрос:
WITH
cteReports (EmpID, FirstName, LastName, MgrID, EmpLevel)
AS
(
SELECT EmployeeID, FirstName, LastName, ManagerID, 1
FROM Employees
WHERE ManagerID IS NULL
UNION ALL
SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID,
r.EmpLevel + 1
FROM Employees e
INNER JOIN cteReports r
ON e.ManagerID = r.EmpID
)
SELECT
FirstName + ' ' + LastName AS FullName,
EmpLevel,
(SELECT FirstName + ' ' + LastName FROM Employees
WHERE EmployeeID = cteReports.MgrID) AS Manager
FROM cteReports
ORDER BY EmpLevel, MgrID
Здесь я публикую о том, как отображается результат:
Мне просто нужно знать, как это показывает сначала менеджер, а потом его подчиненный в цикле. Я предполагаю, что первый оператор sql запускается только один раз и возвращает все идентификаторы сотрудников.
И второй запрос срабатывает многократно, запрашивая базу данных, в которой существует сотрудник с текущим идентификатором менеджера.
Пожалуйста, объясните, как оператор sql выполняется во внутреннем цикле, а также сообщите мне порядок выполнения sql. Спасибо.
МОЯ 2-я фаза вопроса
;WITH Numbers AS
(
SELECT n = 1
UNION ALL
SELECT n + 1
FROM Numbers
WHERE n+1 <= 10
)
SELECT n
FROM Numbers
Q 1) как увеличивается значение N? если значение присваивается N каждый раз, то значение N может быть увеличено, но значение N инициализировано только в первый раз.
Q 2) CTE и рекурсия отношений сотрудников:
Проблема начинается в тот момент, когда я добавляю двух менеджеров и еще несколько сотрудников под вторым менеджером.
Я хочу отобразить первую информацию о менеджере, а в следующих строках только те данные о сотрудниках, которые относятся к подчиненному этого менеджера.
предполагать
ID Name MgrID Level
--- ---- ------ -----
1 Keith NULL 1
2 Josh 1 2
3 Robin 1 2
4 Raja 2 3
5 Tridip NULL 1
6 Arijit 5 2
7 Amit 5 2
8 Dev 6 3
Я хочу отображать результаты таким образом с помощью выражений CTE. Скажите, пожалуйста, что изменить в моем sql, который я дал здесь, чтобы вытащить отношения менеджер-сотрудник. Спасибо.
Я хочу, чтобы результат был таким:
ID Name MgrID nLevel Family
----------- ------ ----------- ----------- --------------------
1 Keith NULL 1 1
3 Robin 1 2 1
2 Josh 1 2 1
4 Raja 2 3 1
5 Tridip NULL 1 2
7 Amit 5 2 2
6 Arijit 5 2 2
8 Dev 6 3 2
Это возможно...?
Хочу провести краткую смысловую параллель с уже правильным ответом.
Проще говоря, рекурсивный CTE можно семантически определить как следующие части:
1: запрос CTE. Также известен как ЯКОРЬ.
2: Рекурсивный запрос CTE для CTE в (1) с UNION ALL (или UNION, EXCEPT или INTERSECT), поэтому возвращается окончательный результат.
3: условие угла / завершения. Это по умолчанию, когда рекурсивный запрос больше не возвращает строк / кортежей.
Небольшой пример, который проясняет картину:
Объяснение: первый запрос CTE возвращает базовых поставщиков (например, листья), которые не поставляют напрямую другому поставщику (-1)
Рекурсивный запрос в первой итерации получает всех поставщиков, которые поставляют поставщикам, возвращенным ANCHOR. Этот процесс продолжается до тех пор, пока условие не вернет кортежи.
UNION ALL возвращает все кортежи по общему количеству рекурсивных вызовов.
Еще один хороший пример можно найти здесь .
PS: Чтобы рекурсивный CTE работал, отношения должны иметь иерархическое (рекурсивное) условие для работы. Пример: elementId = elementParentId .. вы поняли.
источник
Процесс выполнения действительно сбивает с толку с рекурсивным CTE, лучший ответ я нашел на https://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx и аннотацию процесса выполнения CTE как показано ниже.
Семантика рекурсивного выполнения следующая:
источник
источник