以下のようなテーブルがあります。
Id ParentID
1 99
2 9
3 1
4 2
5 4
6 3
そして、各子の最後の祖先を取得するクエリが必要です。
つまり、望ましい結果は
id Lastancestor
1 99
2 9
3 99
4 9
5 9
6 99
大量のデータを持っているので、早急に何かが必要です。
ありがとう。
以下のようなテーブルがあります。
Id ParentID
1 99
2 9
3 1
4 2
5 4
6 3
そして、各子の最後の祖先を取得するクエリが必要です。
つまり、望ましい結果は
id Lastancestor
1 99
2 9
3 99
4 9
5 9
6 99
大量のデータを持っているので、早急に何かが必要です。
ありがとう。
再帰 CTEを使用してこれを実現できます。
;WITH CTE AS (
SELECT Id AS origId, ParentID, 0 AS lvl
FROM mytable
UNION ALL
SELECT c.origId AS origId,
m.ParentID, lvl = lvl + 1
FROM CTE AS c
INNER JOIN mytable AS m ON c.ParentID = m.Id
)
SELECT origId AS id, ParentID AS Lastancestor
FROM (
SELECT origId, ParentID,
ROW_NUMBER() OVER (PARTITION BY origId
ORDER BY lvl DESC) AS rn
FROM CTE) AS t
WHERE t.rn = 1
ここで、CTE のアンカー メンバーはテーブル全体です。Id
再帰は、元の(as としてorigId
) 再帰チェーンを下に伝播しながら、ツリー階層を上ります。再帰は、空のセットが返されるとすぐに終了します。つまり、c.ParentID = m.Id
一致するものが見つからなくなるとすぐに終了します。
必要な結果、つまりLastancestor
perを取得するには、 per が最大(深さ)id
のレコードをフェッチするだけです。これは、ウィンドウ関数を使用して実現されます。 lvl
id
ROW_NUMBER