2016-12-14 4 views
1

У меня есть таблица со следующими столбцамиРекурсивный SQL-запрос с несколькими столбцами

idRelationshipType int, 
idPerson1 int, 
idPerson2 int 

Эта таблица позволяет мне указывать записи в базе данных, которые должны быть связаны друг с другом.

Мне нужно сделать запрос, возвращающий все уникальные идентификаторы, в которых идентификатор человека существует в столбцах idPerson1 или idPerson2. Кроме того, мне нужно, чтобы запрос был рекурсивным, так что, если совпадение найдено в idPerson1, значение для idPerson2 включено в результирующий набор и используется для повторного повторения запроса до тех пор, пока не будет найдено больше совпадений.

Пример данные:

CREATE TABLE [dbo].[tbRelationships] 
(
    [idRelationshipType] [int], 
    [idPerson1] [int] , 
    [idPerson2] [int] 
) 

INSERT INTO tbRelationships (idRelationshipType, idPerson1, idPerson2) 
VALUES (1, 1, 2) 
INSERT INTO tbRelationships (idRelationshipType, idPerson1, idPerson2) 
VALUES (1, 2, 3) 
INSERT INTO tbRelationships (idRelationshipType, idPerson1, idPerson2) 
VALUES (1, 3, 4) 
INSERT INTO tbRelationships (idRelationshipType, idPerson1, idPerson2) 
VALUES (1, 5, 1) 

четыре 'Отношения' определяется здесь. Для этого запроса я буду знать только один из идентификаторов. Мне нужен запрос, который в концепции работает как

SELECT idPerson 
FROM [some query] 
WHERE [the id i have to start with] = @idPerson 
    AND idRelationshipType = @idRelationshipType 

Возвращаемый результат должен быть 5 строк с одного столбца «idPerson», с 1, 2, 3, 4 и 5 в качестве значений строк.

Я пробовал различные комбинации UNPIVOT и рекурсивных CTE, но я не добился большого прогресса.

Любая помощь была бы принята с благодарностью.

Спасибо, Daniel

ответ

1

Я думаю, что это то, что вы хотите:

DECLARE @RelationshipType int 
DECLARE @PersonId int 

SELECT @RelationshipType = 1, @PersonId = 1 

;WITH Hierachy (idPerson1, IdPerson2) 
AS 
(
    --root 
    SELECT R.idPerson1, R.idPerson2 
    FROM tbRelationships R 
    WHERE R.idRelationshipType = @RelationshipType 
    AND  (R.idPerson1 = @PersonId OR R.idPerson2 = @PersonId) 
    --recurse 
    UNION ALL 
    SELECT R.idPerson1, R.idPerson2 
    FROM Hierachy H 
    JOIN tbRelationships R 
      ON (R.idPerson1 = H.idPerson2 
       OR R.idPerson2 = H.idPerson1) 
      AND R.idRelationshipType = @RelationshipType 
) 
SELECT DISTINCT idPerson 
FROM 
(
    SELECT idPerson1 AS idPerson FROM Hierachy 
    UNION 
    SELECT idPerson2 AS idPerson FROM Hierachy 
) H 

По существу, получить первые строки, где требуемый идентификатор в любом столбце, а затем рекурсивный получать все ребенка ids на основе столбца id 2

+0

Это близко, но если вы используете @ personId = 3, он не возвращается 1,2,3,4. Вместо этого он возвращает только 2,3,4. Если вы используете @ personid = 4, возвращается только 3,4. –

+0

Я не понимаю из-за вопроса, почему вы ожидаете результатов, описанных выше! Намерены ли вы возвращаться из id1, а также из id2? В противном случае, если бы 1 прибыл с id = 3? –

+0

В таблице указаны отношения между людьми. Он не является иерархическим - никаких родительских отношений с дочерними элементами ... В этом случае мне нужно получить все отношения для них, которые связаны либо вверх, либо вниз по списку. Когда у меня есть идентификатор человека, мне нужно знать все отношения, которые существуют независимо от того, насколько они отдалены. –

Смежные вопросы