#sql #sql-server #tsql #hierarchical-data #recursive-query
#sql #sql-сервер #tsql #иерархический-данные #рекурсивный-запрос
Вопрос:
Нужна помощь по циклическому запросу sql
моя таблица :
мой ожидаемый результат:
Я могу получить только 1 строку..
declare @ID nvarchar(50) = (select EMP_ID from HRS_WORKFLOW01);
CREATE TABLE #TEMP(EMP_ID NVARCHAR(200),EMP_L1 NVARCHAR(200),EMP_L2 NVARCHAR(200),EMP_L3 NVARCHAR(200),EMP_L4 NVARCHAR(200))
DECLARE @L1 NVARCHAR(50);
DECLARE @L2 NVARCHAR(50);
DECLARE @L3 NVARCHAR(50);
DECLARE @L4 NVARCHAR(50);
SET @L1 = (SELECT L1EmplNo FROM HRS_WORKFLOW01 WHERE EMP_ID =@ID)
INSERT INTO #TEMP (EMP_ID,EMP_L1)VALUES(@ID,@L1)
SET @L2 = (SELECT L1EmplNo FROM HRS_WORKFLOW01 WHERE EMP_ID =@L1)
UPDATE #TEMP SET EMP_L2=@L2 WHERE EMP_ID=@ID
SET @L3 = (SELECT L1EmplNo FROM HRS_WORKFLOW01 WHERE EMP_ID =@L2)
UPDATE #TEMP SET EMP_L3=@L3 WHERE EMP_ID=@ID
SET @L4 = (SELECT L1EmplNo FROM HRS_WORKFLOW01 WHERE EMP_ID =@L3)
UPDATE #TEMP SET EMP_L4=@L4 WHERE EMP_ID=@ID
SELECT * FROM #TEMP
Комментарии:
1. Вы читали руководство по CTE (Common Table Expression)?
2. Пожалуйста, разместите образцы данных в текстовом формате вместо изображений
Ответ №1:
Вам необходимо использовать Recursive CTE
;WITH DATA
AS (SELECT *
FROM (VALUES ('ALI','ABU'),
('JOSH','LIM'),
('JAMES','KAREN'),
('LIM','JERRY'),
('JERRY','GEM')) TC(EMP_ID, EMP_L1)),
REC_CTE
AS (SELECT EMP_ID,
EMP_L1,
Cast(EMP_L1 AS VARCHAR(8000)) AS PARENT,
LEVEL = 1
FROM DATA
UNION ALL
SELECT D.EMP_ID,
D.EMP_L1,
Cast(RC.PARENT '.' D.EMP_L1 AS VARCHAR(8000)),
LEVEL = LEVEL 1
FROM DATA D
JOIN REC_CTE RC
ON RC.EMP_ID = D.EMP_L1)
SELECT TOP 1 WITH TIES EMP_ID,
EMP_L1 = COALESCE(Parsename(PARENT, 1), ''),
EMP_L2 = COALESCE(Parsename(PARENT, 2), ''),
EMP_L3 = COALESCE(Parsename(PARENT, 3), ''),
EMP_L4 = COALESCE(Parsename(PARENT, 4), '')
FROM REC_CTE
ORDER BY Row_number()OVER(PARTITION BY EMP_ID ORDER BY LEVEL DESC)
OPTION (MAXRECURSION 0)
Результат :
╔════════╦════════╦════════╦════════╦════════╗
║ EMP_ID ║ EMP_L1 ║ EMP_L2 ║ EMP_L3 ║ EMP_L4 ║
╠════════╬════════╬════════╬════════╬════════╣
║ ALI ║ ABU ║ ║ ║ ║
║ JAMES ║ KAREN ║ ║ ║ ║
║ JERRY ║ GEM ║ ║ ║ ║
║ JOSH ║ LIM ║ JERRY ║ GEM ║ ║
║ LIM ║ JERRY ║ GEM ║ ║ ║
╚════════╩════════╩════════╩════════╩════════╝
Примечание: при этом учитывается, что может быть не более 4 уровней. Чтобы разделить данные на разные столбцы, я использовал PARSENAME
функцию, которая не будет работать, если у вас более 4 уровней.
Если вы не хотите разделять родительские элементы на разные столбцы, удалите PARSENAME
и выберите PARENT
только столбец.
Комментарии:
1. @KyLim — У вас может быть любое их количество
emp_id
, это не проблема, если оно всегдаEMP_L1
EMP_L4
2. Сообщение 530, уровень 16, состояние 1, Рабочий процесс процедуры, строка 23 Оператор завершен. Максимальная рекурсия 100 была исчерпана до завершения инструкции. , я получаю эту ошибку xD
3. ИСПОЛЬЗУЙТЕ ОПЦИЮ (MAXRECURSION 0); в конце инструкции.