我遇到了一个问题,我想知道是否有一个优雅的解决方案。这是一个真正的商业问题而不是课堂作业!
我有一张包含数千条记录的表,其中一些是彼此相关的组。
数据库是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。
我希望能够在网格中显示此表中的所有记录。 然后,我希望用户能够右键单击任何记录 组,并为系统找到所有相关记录并显示它们 在某种树上。
现在我显然可以强行解决这个问题,但我想问一下 社区,如果他们能看到更优雅的答案。
答案 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
答案 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.