CTE再帰を使用しようとしています。これが私のシナリオです SQL Fiddle 。これは単純なツリー構造です。
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) ;
簡単に言えば、ユーザーは私にID(1092など)を与えます。テーブル内のすべての行を再帰的に実行し、ユーザーが指定したIDで始まるID(ID1 + ID2)のマージを実行します。
私はこのようなものを取得したいと思います(IDと呼ばれる1つの列だけで):
ID 1092、 284917、 248957、 789475、 1、 2、 3
これらのIDを指すノードがないため、ID4と6は結果リストに含まれていないことに注意してください。
これが私の解決策です。以前のコメントで述べたように、これはスタイル的に最も美しいソリューションではありませんが、機能します。
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