确定SQL数据库中记录的层次结构

时间:2009-10-16 14:47:45

标签: sql sql-server sql-server-2005 tsql hierarchical-data

我遇到了一个问题,我想知道是否有一个优雅的解决方案。这是一个真正的商业问题而不是课堂作业!

我有一张包含数千条记录的表,其中一些是彼此相关的组。

数据库是SQL 2005。

ID是主键。如果记录替换了先前的记录,则该记录的ID位于REP_ID列中。

ID   REP_ID    

E     D
D     B
C     B
B     A
A     NULL

所以在这个例子中,A是原始行,B代替A,C代替B失败,D代替B成功,最后E代替D。

我希望能够在网格中显示此表中的所有记录。 然后,我希望用户能够右键单击任何记录 组,并为系统找到所有相关记录并显示它们 在某种树上。

现在我显然可以强行解决这个问题,但我想问一下 社区,如果他们能看到更优雅的答案。

3 个答案:

答案 0 :(得分:2)

这是你需要的recursive CTE,类似于(未经测试的)

;WITH myCTE AS
(
    SELECT
       ID
    FROM
       myTable
    WHERE
       REP_ID IS NULL
    UNION ALL
    SELECT
       ID
    FROM
       myTable T
       JOIN
       myCTE C ON T.REP_ID = C.ID
)
SELECT
    *
FROM
    myCTE

然而,链接C-> B和D-> B

  • 所以你想要C-> B或两者兼而有之?
  • 你想要排名吗?
  • 等?

答案 1 :(得分:0)

使用CTE构建层次结构。像

这样的东西
CREATE TABLE #test(ID CHAR(1), REP_ID CHAR(1) NULL)

INSERT INTO #test VALUES('E','D')
INSERT INTO #test VALUES('D','B')
INSERT INTO #test VALUES('C','B')
INSERT INTO #test VALUES('B','A')
INSERT INTO #test VALUES('A',NULL)


WITH tree(  ID, 
        REP_ID,
        Depth
        )
AS
(
    SELECT 
    ID,
    REP_ID,         
    1 AS [Depth]                   
    FROM
    #test
    WHERE
    REP_ID IS NULL

    UNION ALL

    SELECT 
    [test].ID,
    [test].REP_ID,          
    tree.[Depth] + 1 AS [Depth]                   
    FROM
    #test [test]
    INNER JOIN
    tree
    ON
    [test].REP_ID = tree.ID
)

SELECT * FROM tree

答案 2 :(得分:-1)

您可能已经考虑过了,但是您是否只想添加一行来存储“original_id”?与构建从谁那里继承的树相比,这会使你的查询闪电般快速。

除此之外,只需谷歌“SQL树DFS”。

请确保您的DFS优化如下:如果您知道大多数记录只有< = 3版本,您可以从3向关节开始,立即找到A,B和C.