Sql server 2008 SQL Server 2008中提供的数据结构

Sql server 2008 SQL Server 2008中提供的数据结构,sql-server-2008,stored-procedures,Sql Server 2008,Stored Procedures,我在SQLServer2008中创建了我的第一个存储过程,我试图解决的问题需要某种类型的数据结构,该结构可以保存与多个其他字符串(哈希或某种树)关联的字符串。然而,我似乎在网上找不到这方面的任何例子。有没有一种方法可以在sql存储过程中使用映射或树,或者假设这种繁重的工作是由代码外部完成的 更具体地说,它涉及组织结构图。我有一个查询,可以生成每个员工和他们的直接主管,但是团队其他成员想要的输出是一个结果集,所有人都在给定的个人下面报告,但在给定的个人下面有一个额外的列供他们的主管使用。看起来可能

我在SQLServer2008中创建了我的第一个存储过程,我试图解决的问题需要某种类型的数据结构,该结构可以保存与多个其他字符串(哈希或某种树)关联的字符串。然而,我似乎在网上找不到这方面的任何例子。有没有一种方法可以在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
有了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中支持哪种类型的结构来完成此任务。

您可能需要使用递归来获取所需的信息(使用CTE)

表结构很简单:

ID
Name
SupervisorID

如果您需要有关CTE的帮助,请告诉我。

以下是一个树示例:

--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)

+1对于一个实际的数据库实现,我希望它实际上是内置的数据结构,而不是必须输入代码来使用临时表创建自己的数据结构,但很高兴至少得到了一个明确的答案。