Структуры данных, доступные в SQL Server 2008 - PullRequest
2 голосов
/ 09 августа 2011

Я создаю свою первую хранимую процедуру в SQL Server 2008, и проблема, которую я пытаюсь решить, требует какой-то структуры данных, которая может содержать строку, связанную с несколькими другими строками, либо хеш, либо какое-то дерево.Однако я не могу найти какие-либо примеры этого в Интернете.Есть ли способ использовать карты или деревья в хранимых процедурах sql, или предполагается, что этот вид тяжелой работы выполняется в коде снаружи?

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

Например:

Jim and Billy report to Bob, Paul and April report to Kurt 
Kurt and Ed report to Tim, Laurie and Bob report to George
George reports to Maggie
Maggie and Tim report to Jessica

При вводе Джессики информация, которую мне нужно распечатать, будет выглядеть так:

Jim reports to Maggie
Billy reports to Maggie
Paul reports to Tim
April reports to Tim
Kurt reports to Tim
Ed reports to Tim
Laurie reports to Maggie
Bob reports to Maggie
George reports to Maggie
Tim reports to Jessica
Maggie reports to Jessica

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

Ответы [ 2 ]

4 голосов
/ 09 августа 2011

Возможно, вы захотите использовать рекурсию для получения необходимой информации (используйте CTE).

Структура таблицы проста:

ID
Name
SupervisorID

Дайте мне знать, если вам нужна помощь с CTE.

1 голос
/ 11 августа 2011

Вот пример дерева:

--recursive CTE tree example
DECLARE @Contacts table (id int, first_name varchar(10), reports_to_id int)
INSERT @Contacts VALUES (1,'Jerome', NULL )  -- tree is as follows:
INSERT @Contacts VALUES (2,'Joe'   ,'1')     --                      1-Jerome
INSERT @Contacts VALUES (3,'Paul'  ,'2')     --                     /        \
INSERT @Contacts VALUES (4,'Jack'  ,'3')     --              2-Joe           9-Bill
INSERT @Contacts VALUES (5,'Daniel','3')     --            /       \              \
INSERT @Contacts VALUES (6,'David' ,'2')     --     3-Paul          6-David       10-Sam
INSERT @Contacts VALUES (7,'Ian'   ,'6')     --    /      \            /    \
INSERT @Contacts VALUES (8,'Helen' ,'6')     -- 4-Jack  5-Daniel   7-Ian    8-Helen
INSERT @Contacts VALUES (9,'Bill ' ,'1')     --
INSERT @Contacts VALUES (10,'Sam'  ,'9')     --

DECLARE @Root_id  int

--get complete tree---------------------------------------------------
SET @Root_id=null
PRINT '@Root_id='+COALESCE(''''+CONVERT(varchar(5),@Root_id)+'''','null')
;WITH StaffTree AS
(
    SELECT 
        c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf
        FROM @Contacts                  c
            LEFT OUTER JOIN @Contacts  cc ON c.reports_to_id=cc.id
        WHERE c.id=@Root_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL)
    UNION ALL
        SELECT 
            s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1
        FROM StaffTree            t
            INNER JOIN @Contacts  s ON t.id=s.reports_to_id
    WHERE s.reports_to_id=@Root_id OR @Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree ORDER BY LevelOf,first_name


--get 2 and all below---------------------------------------------------
SET @Root_id=2
PRINT '@Root_id='+COALESCE(''''+CONVERT(varchar(5),@Root_id)+'''','null')
;WITH StaffTree AS
(
    SELECT 
        c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf
        FROM @Contacts                  c
            LEFT OUTER JOIN @Contacts  cc ON c.reports_to_id=cc.id
        WHERE c.id=@Root_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL)
    UNION ALL
        SELECT 
            s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1
        FROM StaffTree            t
            INNER JOIN @Contacts  s ON t.id=s.reports_to_id
    WHERE s.reports_to_id=@Root_id OR @Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree ORDER BY LevelOf,first_name

--get 6 and all below---------------------------------------------------
SET @Root_id=6
PRINT '@Root_id='+COALESCE(''''+CONVERT(varchar(5),@Root_id)+'''','null')
;WITH StaffTree AS
(
    SELECT 
        c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf
        FROM @Contacts                  c
            LEFT OUTER JOIN @Contacts  cc ON c.reports_to_id=cc.id
        WHERE c.id=@Root_id OR (@Root_id IS NULL AND c.reports_to_id IS NULL)
    UNION ALL
        SELECT 
            s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1
        FROM StaffTree            t
            INNER JOIN @Contacts  s ON t.id=s.reports_to_id
    WHERE s.reports_to_id=@Root_id OR @Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree ORDER BY LevelOf,first_name

ВЫХОД:

@Root_id=null
id          first_name reports_to_id Manager_id  Manager_first_name LevelOf
----------- ---------- ------------- ----------- ------------------ -----------
1           Jerome     NULL          NULL        NULL               1
9           Bill       1             1           Jerome             2
2           Joe        1             1           Jerome             2
6           David      2             2           Joe                3
3           Paul       2             2           Joe                3
10          Sam        9             9           Bill               3
5           Daniel     3             3           Paul               4
8           Helen      6             6           David              4
7           Ian        6             6           David              4
4           Jack       3             3           Paul               4

(10 row(s) affected)

@Root_id='2'
id          first_name reports_to_id Manager_id  Manager_first_name LevelOf
----------- ---------- ------------- ----------- ------------------ -----------
2           Joe        1             1           Jerome             1
6           David      2             2           Joe                2
3           Paul       2             2           Joe                2
5           Daniel     3             3           Paul               3
8           Helen      6             6           David              3
7           Ian        6             6           David              3
4           Jack       3             3           Paul               3

(7 row(s) affected)

@Root_id='6'
id          first_name reports_to_id Manager_id  Manager_first_name LevelOf
----------- ---------- ------------- ----------- ------------------ -----------
6           David      2             2           Joe                1
8           Helen      6             6           David              2
7           Ian        6             6           David              2

(3 row(s) affected)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...