0

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

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

数据库是 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。

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

现在我显然可以强力解决这个问题,但我想问问社区他们是否能看到更优雅的答案。

4

3 回答 3

2

这是您需要的递归 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 还是两者兼而有之?
  • 你要排名吗?
  • ETC?
于 2009-10-16T15:07:26.650 回答
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
于 2009-10-16T15:14:43.500 回答
-1

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

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

只需确保您对 DFS 进行了如下优化:如果您知道大多数记录只有 <=3 次修订,则可以从 3 路联合开始立即找到 A、B 和 C。

于 2009-10-16T14:56:35.580 回答