How to get all connected values as a single column
-
01-10-2020 - |
Question
I'm trying to use CTE recursion. This is my scenario SQL Fiddle. It is a simple tree structure:
CREATE TABLE [dbo].[AL](
[IdAL] [int] IDENTITY(1,1) NOT NULL,
[ID1] [int] NOT NULL,
[ID2] [int] NOT NULL,
CONSTRAINT [PK_AL] PRIMARY KEY CLUSTERED
(
[IdAL] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] ;
INSERT INTO AL (ID1, ID2)
VALUES (1092, 284917),
(1092, 248957),
(1092, 789475),
( 1, 789475),
( 1, 2),
( 3, 2),
( 6, 4) ;
Simply put, the user gives me an id (e.g. 1092). I would recursively run all rows in the table and do the merge of the id (ID1 + ID2) starting with the id provided by the user.
I would like to get something like this (in just one column called ID):
ID 1092, 284917, 248957, 789475, 1, 2, 3
Note that id 4 and 6 are not in the result list because there is no node that points to these ids.
Solution
this is my solution. As I mentioned in a previous comment, it's not the prettiest solution stylistically, but it works.
DECLARE @Id int = 1092
DECLARE @i INT = 0,
@IdToProcess INT = 0
DECLARE @t TABLE ( Id INT,
Processed BIT
)
INSERT INTO @t (Id, Processed)
VALUES (@Id, 0)
WHILE (1 = 1 OR @i <= 100)
BEGIN
SET @i = @i +1
SET @IdToProcess = 0
SELECT @IdToProcess = MIN(Id)
FROM @t
WHERE Processed = 0
SET @IdToProcess = ISNULL(@IdToProcess, 0)
IF @IdToProcess <= 0
BEGIN
BREAK
END
INSERT INTO @t (Id, Processed)
SELECT AL.Id2, 0
FROM dbo.AL AL
WHERE AL.Id1 = @IdToProcess
AND NOT EXISTS (SELECT 1 FROM @t T WHERE T.Id = AL.Id2)
UNION
SELECT AL.Id1, 0
FROM dbo.AL AL
WHERE AL.Id2 = @IdToProcess
AND NOT EXISTS (SELECT 1 FROM @t T WHERE T.Id = AL.Id1)
UPDATE @t
SET Processed = 1
WHERE Id = @IdToProcess
END
SELECT * FROM @T
Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange