patternsqlMinor
Making a recursive CTE like query, but for many records
Viewed 0 times
querybutctelikerecordsrecursiveformanymaking
Problem
I have a table with a hierarchy ( with a recursive parentID column), for one record, I know how to get the last parent record, with the following code :
It works as long as I'm working with one id, here @Id.
But I can't find a way to do the same but for a list of Ids, without using cursors, as CTE seems to be OK only when y'oure working on one record.
Could someone point me at the right direction ?
Many thanks
declare @Id integer
;WITH CTE AS
(
SELECT a.[Id],
a.[ParentId]
FROM [Area] a WITH (NOLOCK)
where a.[Id] = @Id
UNION ALL
SELECT a.[Id],
a.[ParentId]
FROM [Area] a WITH (NOLOCK)
INNER JOIN CTE cte ON cte.[ParentId] = a.[Id]
)
SELECT top 1 a.[Id]
FROM CTE a
WHERE a.ParentId is nullIt works as long as I'm working with one id, here @Id.
But I can't find a way to do the same but for a list of Ids, without using cursors, as CTE seems to be OK only when y'oure working on one record.
Could someone point me at the right direction ?
Many thanks
Solution
Assuming the original table design is somewhat like this:
Sample data:
The following recursive CTE query finds roots for the
The output shows each supplied
CREATE TABLE dbo.Area
(
RowID integer PRIMARY KEY,
GroupID integer NOT NULL,
ParentID integer NULL,
);Sample data:
INSERT dbo.Area
(RowID, GroupID, ParentID)
VALUES
(1, 1, NULL), -- Root
(2, 1, 1),
(3, 1, 2),
(4, 2, NULL), -- Root
(5, 2, 4),
(6, 2, 5),
(7, 2, 6);The following recursive CTE query finds roots for the
RowID list given in the anchor:WITH R AS
(
SELECT
A.RowID,
A.RowID AS OriginalRowID,
A.ParentID
FROM dbo.Area AS A
WHERE
A.RowID IN (3, 7)
UNION ALL
SELECT
A.RowID,
R.OriginalRowID,
A.ParentID
FROM dbo.Area AS A
JOIN R
ON R.ParentID = A.RowID
)
SELECT
R.OriginalRowID,
R.RowID
FROM R
WHERE
R.ParentID IS NULL
ORDER BY
R.OriginalRowID
OPTION (MAXRECURSION 0);The output shows each supplied
RowID and the root for that group:Code Snippets
CREATE TABLE dbo.Area
(
RowID integer PRIMARY KEY,
GroupID integer NOT NULL,
ParentID integer NULL,
);INSERT dbo.Area
(RowID, GroupID, ParentID)
VALUES
(1, 1, NULL), -- Root
(2, 1, 1),
(3, 1, 2),
(4, 2, NULL), -- Root
(5, 2, 4),
(6, 2, 5),
(7, 2, 6);WITH R AS
(
SELECT
A.RowID,
A.RowID AS OriginalRowID,
A.ParentID
FROM dbo.Area AS A
WHERE
A.RowID IN (3, 7)
UNION ALL
SELECT
A.RowID,
R.OriginalRowID,
A.ParentID
FROM dbo.Area AS A
JOIN R
ON R.ParentID = A.RowID
)
SELECT
R.OriginalRowID,
R.RowID
FROM R
WHERE
R.ParentID IS NULL
ORDER BY
R.OriginalRowID
OPTION (MAXRECURSION 0);Context
StackExchange Database Administrators Q#63032, answer score: 5
Revisions (0)
No revisions yet.