我知道CTE存在很多问题,但我仍然不知道该怎么做。 我有带有列的表Messages:id和previousMessageId。如何获得ID = 957的父母-应该是950。
table Messages
--------------
id | previousMessageId
957 | 956
956 | 950
950 | NULL
这是我的查询
WITH previous AS
(
SELECT id
FROM Messages
WHERE id = 957
UNION ALL
SELECT cur.id
FROM Messages cur
INNER JOIN previous ON cur.previousMessageID = previous.id
)
SELECT * FROM previous
它给了我
957
958
但是结果应该是:950
答案 0 :(得分:3)
您可以尝试以下操作。
declare @table table(id int, previousMessageId int)
insert into @table select 957 , 956
insert into @table select 956 , 950
insert into @table select 950 , NULL
insert into @table select 999 , 998
insert into @table select 998 , 997
insert into @table select 997 , NULL
;WITH previous
AS (SELECT id,
previousmessageid
FROM @table
WHERE id = 957
UNION ALL
SELECT cur.id,
cur.previousmessageid
FROM @table cur
INNER JOIN previous
ON cur.id = previous.previousmessageid)
SELECT ID
FROM previous
WHERE previousmessageid IS NULL
在上面的示例中,ID 957为950,ID为999
答案 1 :(得分:0)
您可以使用第二列来表示父代ID。父层将具有一个空列,子层将随后引用父层。
WITH previous AS
(
SELECT id, null as parentid
FROM Messages
WHERE id = 957
UNION ALL
SELECT cur.id, cur.previousMessageID
FROM Messages cur
INNER JOIN previous ON cur.previousMessageID = previous.id
)
SELECT ParentID FROM previous where ParentID is not null
答案 2 :(得分:0)
declare @table table(id int, previousMessageId int)
insert into @table select 957 , 956
insert into @table select 956 , 950
insert into @table select 950 , NULL
insert into @table select 999 , 998
insert into @table select 998 , 997
insert into @table select 997 , NULL;
with cte as (
-- base case - get all records with no parent
select *,
cast(concat('/', id, '/') as varchar(max)) as [path],
id as [root]
from @table
where previousMessageId is null
union all
-- recursive step
select child.*,
concat(parent.path, child.id, '/'),
parent.root
from @table as child
join cte as parent
on parent.id = child.previousMessageId
)
select *
from cte
where id = 957;
最终输出中的root
列是该祖先行中以该特定ID结尾的第一行。至于我的实现方式,诀窍本质上是始终将parent.root
推进递归步骤。