请不要在没有阅读的情况下将问题标记为重复.我发布了一个类似的问题,但是堆叠流动的社区成员要求我单独发布修改后的问题,因为解决方案更加复杂,提供了一个小的,小的修改.
假设您有以下架构:
CREATE TABLE Data
(
ID INT,
CXL INT
)
INSERT INTO Data (ID, CXL)
SELECT 1, NULL
UNION
SELECT 2, 1
UNION
SELECT 3, 2
UNION
SELECT 5, 3
UNION
SELECT 6, NULL
UNION
SELECT 7, NULL
UNION
SELECT 8, 7
Run Code Online (Sandbox Code Playgroud)
列CXL是取消特定ID的ID.因此,例如,ID为1的表中的第一行是好的,直到它被ID:2(CXL列)取消.ID:2一直很好,直到它被ID:3取消.ID:3是好的,直到它被ID:5取消,所以在这个序列中,最后一个"GOOD"ID是ID:5.
我想找到"GOOD"ID以及启动EACH链的原始ID.所以在这个例子中它将是:
Original ID | Latest GOOD ID
1 5
6 6
7 8
Run Code Online (Sandbox Code Playgroud)
如果你想玩这个,这是一个小提琴:http: //sqlfiddle.com/#!6/68ac48/1
花了几分钟时间为这个挖掘正确的CTE:
WITH ids AS (
SELECT
ID,
ID AS orig FROM Data d1 WHERE CXL IS NULL
UNION ALL
SELECT
d2.ID,
orig
FROM ids i
INNER JOIN Data d2 ON d2.CXL = i.ID
)
SELECT
orig AS [Original Id],
MAX(ID) AS [Latest Good Id]
FROM ids
GROUP BY orig
Run Code Online (Sandbox Code Playgroud)
这假设取消ID总是高于它取消的ID,当然......
基本上,每次递归时,它会再次为该行重新选择原始id.一旦递归完成,GROUP BY获得原始id和最新的只是一个简单的问题.