0

以下のようなテーブルがあります。

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

大量のデータを持っているので、早急に何かが必要です。

ありがとう。

4

2 に答える 2

2

再帰 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一致するものが見つからなくなるとすぐに終了します。

必要な結果、つまりLastancestorperを取得するには、 per が最大(深さ)idのレコードをフェッチするだけです。これは、ウィンドウ関数を使用して実現されます。 lvlidROW_NUMBER

デモはこちら

于 2015-09-09T21:08:14.460 に答える