2015-10-02 8 views
1

У меня есть таблица с двумя столбцами, а именно cola и colb, как показано ниже:SQL Server 2008 R2: Подготовка рекурсивный запрос

Таблица: Test

create table Test 
(
    cola int, 
    colb int 
); 

Records, я вошел в:

Cola Colb 
------------ 
1  2 
1  3 
1  4 
2  5 
2  6 
2  3 
3  2 
3  4 
3  7 
3  10 
10  11 
11  12 
11  13 
11  14 
12  15 
13  16 
14  99 
15  88 
16  77 

Примечание: Теперь я хочу показать только записи, связанные со значением У меня есть проход. Например, если я передаю значение как 1, тогда он должен отобразить мне связанный номер с ним и сформировать соединение как дерево.

enter image description here

enter image description here

Для этого я использую следующий сценарий:

WITH CTE 
AS 
(
    SELECT Cola,Colb 
    FROM Test 
    WHERE Cola IN 
    (
     SELECT Colb AS Colb 
     FROM Test 
     WHERE Cola = '1' 
    ) 
), 
outerCTE1 AS 
( 
    SELECT Cola,Colb FROM CTE 
    UNION 
    SELECT Cola,Colb FROM Test 
    WHERE Cola IN (SELECT Colb FROM CTE) 
), 
OuterCTE2 AS 
(
    SELECT Cola,Colb FROM OuterCTE1 
    WHERE Colb NOT IN (SELECT Cola FROM CTE) 
    UNION 
    SELECT Cola,Colb 
    FROM Test 
    WHERE Cola = '1' 
), 
lastCTE AS 
( 
    SELECT Cola,Colb,ROW_NUMBER() OVER(PARTITION BY Colb ORDER BY Cola) rn FROM outerCTE2 
) 
SELECT Cola,Colb FROM lastCTE 
WHERE rn <=1 
ORDER BY CASE WHEN Cola = '1' THEN 1 ELSE 2 END,Cola; 

Но: Проблема заключается в том, что я просто в состоянии производить записи до 11, но я хотите, чтобы все записи были записаны до конца в зависимости от того, какой матч найден до конца. Итак, как написать рекурсивный запрос для этой ситуации?

+0

2 -> 3 и 3 -> 2 .. как вы хотите справиться с этим делом? – DarkKnight

+0

@ DarkKnight, да! Это самая большая задача, которую я чувствую. Если 2 -> 3 уже выше, то 3 -> 2 не должно появляться в приведенной ниже таблице. – MAK

+0

@DarkKnight, и если я передал '3' в качестве своего идентификатора, тогда 3 -> 2 появится первым, а 2 -> 3 не появится в следующий раз. – MAK

ответ

1
;WITH CTE AS 
    (
     SELECT COLA,COLB,','+CAST(COLA AS VARCHAR(MAX))+',' AS CHCK FROM TEST WHERE COLA=1 
     UNION ALL 
     SELECT C1.COLA,C1.COLB,C.CHCK+CAST(C1.cola AS VARCHAR(MAX))+',' 
     FROM CTE C INNER JOIN TEST C1 ON C.colb = C1.cola 
     WHERE CHARINDEX(','+CAST(C.colb AS VARCHAR(MAX))+',',C.CHCK)=0 
    ) 

    SELECT DISTINCT COLA,COLB FROM CTE ORDER BY COLA 
+0

Если я передаю ID = '1', то он дает ошибку:' Оператор завершен. Максимальная рекурсия 100 была исчерпана до завершения заявки. ' – MAK

+0

Вам нужно добавить« ** option (maxrecursion 0) ** »в конце инструкции SELECT. Пожалуйста, обратитесь к [максимальная рекурсия 100 была исчерпана] (http://www.kodyaz.com/forums/thread/1761.aspx) и для [примера рекурсивной функции SQL] (http://www.kodyaz.com/ статьи/sql-server-t-sql-split-function.aspx) – Eralper

+0

@Eralper, да! Я сделал, но результат повторяется долго, без конца. Все еще получается неправильный результат. Что ж! Благодарим вас за ценный комментарий. – MAK