Je sais qu'il y avait beaucoup de questions sur le CTE, mais je ne sais toujours pas comment faire. J'ai des messages de table avec des colonnes: id et previousMessageId. Comment puis-je obtenir le parent pour id = 957 - il devrait être: 950.
957 958
Voici ma requête:
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
Cela donne moi:
table Messages -------------- id | previousMessageId 957 | 956 956 | 950 950 | NULL
Mais le résultat devrait être: 950
3 Réponses :
Vous pouvez utiliser une deuxième colonne pour désigner l'ID parent. Le calque parent aura une colonne nulle, le calque enfant référencera alors le calque parent.
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
il donne: id parentid 957 NULL 958957
J'ai modifié la requête pour afficher uniquement le parentid là où il n'est pas nul.
Vous pouvez essayer comme suit.
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
Dans l'exemple ci-dessus, pour l'ID 957, vous obtiendrez 950 et pour l'ID 999, vous obtiendrez 997
Merci beaucoup. :)
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;
The root column in the final output is the first in the line of ancestors that ends with that particular ID. As to how I accomplished it, the trick is essentially always carrying the parent.root forward through the recursion step.
Fascinant. Vous n'avez même pas 955 dans les données, et la requête est censée renvoyer cela?
Mon erreur, bien sûr 950, très désolé.