Рекурсия T-SQL; Несколько рекурсий? - PullRequest
3 голосов
/ 03 сентября 2011

Я пытаюсь осмыслить решение проблемы, возникающей у меня с помощью рекурсии, и я не могу полностью сосредоточиться на этом. У меня есть три стола. Мы назовем их DocGroup, GroupGroup и GroupUser. В таблице DocGroup есть нанимаемая структура одной записи, которая указывает другую запись в качестве ее родителя и так далее, пока запись не станет ее собственным родителем.

Doc Group
1   1
2   2
3   2
4   3
5   2
6   4

GroupGroup содержит групповое вложение:

Group    MemberGroup
4        2
4        1

GroupUser отображает группу на количество пользователей:

Group    User   Key
1        1      ABC
1        3      BCD
1        4      CDE
2        1      DEF
2        2      EFG
2        3      FGH
3        3      GHI
4        2      HIJ
4        3      IJK
4        4      JKL

Итак, я хотел бы указать пользователя и документ и получить список всех ключей для этой комбинации. Например, если я выбираю пользователя 2 и документ 2, мне нужно вернуть «EFG», но если я выберу документ 6 и пользователя 3, мне нужно вернуть «IJK», «GHI», «FGH» и «BCD», потому что группа 2 и 1 находятся в группе 4, а группа 4 = документ 4, в котором есть группа 3. Во всех случаях мне нужно получить запись только для указанного пользователя.

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

Ответы [ 2 ]

2 голосов
/ 03 сентября 2011

ОК, вот ответ:

DECLARE @Key varchar(max)

;WITH DocBase AS (
    SELECT Doc, Group
        FROM DocGroup
        WHERE Doc = @Doc
    UNION ALL
    SELECT DocGroup.Doc, DocGroup.Group
        FROM DocGroup INNER JOIN DocBase
            ON DocGroup.Doc = DocBase.Group
        WHERE DocBase.Doc <> DocBase.Group --to prevent infinite recursion
    ), GroupNesting AS (
    SELECT Doc
        FROM DocBase
    UNION ALL
    SELECT MemberGroup
        FROM GroupGroup.Group = GroupNesting.Doc
    ), GroupList AS (
    SELECT DISTINCT Doc
        FROM GroupNesting
    ), KeyList AS (
    SELECT Key
        FROM GroupList INNER JOIN GroupUser
            ON GroupList.Doc = GroupUser.Group
        WHERE User = @User
    )
SELECT @Key = COALESE(@Key, '') + Key
    FROM Key

SELECT @Key

Я мог бы использовать любое из предложений от http://www.simple -talk.com / sql / t-sql-программирования / concatenating-row-values-in-transact-sql / для выполнения окончательного конкатенация, но я выбрал этот метод, потому что он самый простой, и я все равно помещаю его в процедуру.

1 голос
/ 03 сентября 2011

Я должен опубликовать это, потому что я свирепый эгоист:

Дзен Рекурсии

А если серьезно, то так мы и сделали в тот день,В наши дни вы будете использовать общее табличное выражение .

HTH.

...