以前の回答は消去されました。私は今あなたがしようとしていることを完全に理解しています。このソリューションは、あなたの "ツリー"が3レベルまで深い場合に機能します。値(7,20)を挿入した場合は、LEFT JOINとUNION ALLを追加する必要があります。
これはまた、recursive CTEを使用してよりきれいに行うこともできますが、固定数のレベルを扱う場合は、この手法のほうが優れています。
-- your table
use tempdb
go
if object_id('dbo.mytable') is not null drop table dbo.mytable;
create table dbo.mytable
(
I1 int not null,
I2 int not null,
constraint pk_cl_mytable primary key clustered(I1,I2)
);
go
insert dbo.mytable values (1,3),(4,6),(2,5),(3,7),(6,9),(8,11);
go
-- solution
WITH flatten AS
(
SELECT
L1 = t1.I1,
L2 = t1.I2,
L3 = t2.I2
FROM dbo.mytable t1
LEFT JOIN dbo.mytable t2 ON t1.I2 = t2.I1
),
setGroups AS
(
SELECT [group] = row_number() over (order by L1), *
FROM flatten
WHERE L1 NOT IN (SELECT L2 FROM flatten)
)
SELECT [group], L1 FROM setGroups
UNION ALL
SELECT [group], L2 FROM setGroups WHERE L2 IS NOT NULL
UNION ALL
SELECT [group], L3 FROM setGroups WHERE L3 IS NOT NULL
ORDER BY [group]; -- not required, including for presentation purposes
結果:
group L1
-------------------- -----------
1 1
1 3
1 7
2 5
2 2
3 4
3 6
3 9
4 11
4 8
必要な場合は、各ノードのレベルを呼び出すために、静的なLVL値を含めることで、階層内の各ノードのレベルを含めることができます
WITH flatten AS
(
SELECT
L1 = t1.I1,
L2 = t1.I2,
L3 = t2.I2
FROM dbo.mytable t1
LEFT JOIN dbo.mytable t2 ON t1.I2 = t2.I1
),
setGroups AS
(
SELECT [group] = row_number() over (order by L1), *
FROM flatten
WHERE L1 NOT IN (SELECT L2 FROM flatten)
)
SELECT [group], L1, lvl = 1 FROM setGroups
UNION ALL
SELECT [group], L2, lvl = 2 FROM setGroups WHERE L2 IS NOT NULL
UNION ALL
SELECT [group], L3, lvl = 3 FROM setGroups WHERE L3 IS NOT NULL
ORDER BY [group], lvl; -- not required, including for presentation purposes
結果:
group L1 lvl
-------- --- ----
1 1 1
1 3 2
1 7 3
2 2 1
2 5 2
3 4 1
3 6 2
3 9 3
4 8 1
4 11 2
「これを行う方法racleはSQLサーバで先に接続する "という質問ですか? –
あなたはどのSQL Serverを使用していますか? –
テーブルから期待される結果の価値をどのように考え出しましたか? –