0

現在の ID (キー) の列と、以前の ID を含む 2 番目の列だけで構成される db テーブルがあります。ID は特定のオブジェクト用ですが、定期的に変更する必要があります。ID の変更の跡をたどり、オブジェクトの ID 系統全体を出力したいと考えています。テーブルをテキストに変換し、リストを使用した後、c# でこれを行いました。しかし、代わりに完全な系統のテーブルを再帰できる c# で使用できる SQL クエリはありますか?

表: 関連 ID

CurrID,PrevID (テーブル)

2,1

4,3

101,2

系統を生成します:

1 -> 2 -> 101

3 -> 4

ありがとうございました。

4

1 に答える 1

0

これは、MS SQL 2005以降で、共通のテーブル式を使用して実現できます(http://msdn.microsoft.com/en-us/library/ms186243(v=sql.105).aspxを参照)。

; -- You'll only need this if it's not the first statement in the batch
WITH Recursive AS (
  SELECT CurrID AS ID, CAST(CurrID AS nvarchar) AS Path
  FROM SourceTable
  WHERE PrevID IS NULL -- You need to anchor your first result

  UNION ALL

  SELECT S.CurrID, P.Path + ' > ' + CAST(CurrID AS nvarchar)
  FROM SourceTable S 
  INNER JOIN Recursive R ON R.CurrID = S.PrevID
)
SELECT * FROM Recursive

次に、最終的なクエリをフィルタリングして、必要なものを取得できます。上から下まで完全に一意のパスのみを除外するには、少しの創造性が必要ですが、これは次のように行うことができます(これをテストできなかったため、少し改良が必要な場合があります)。

; -- You'll only need this if it's not the first statement in the batch
WITH Recursive AS (
  SELECT CurrID AS ID, CAST(CurrID AS nvarchar) AS Path, 0 AS Depth
  FROM SourceTable
  WHERE PrevID IS NULL -- You need to anchor your first result

  UNION ALL

  SELECT S.CurrID, P.Path + ' > ' + CAST(CurrID AS nvarchar), P.Depth + 1
  FROM SourceTable S 
  INNER JOIN Recursive R ON R.CurrID = S.PrevID
)
SELECT Path 
FROM Recursive A
LEFT JOIN Recursive B ON B.Path LIKE A.Path + '%' AND A.Depth < B.Depth
WHERE B.Path IS NULL

大規模なデータセットでは、このような文字列処理は高速ではないため、この方法で処理する場合は注意が必要です。

SQL 2008には、と呼ばれるデータ型hierarchyidがあります。これも便利です。私はそれを使ったことがないので、本当に助けることはできませんが、興味があれば、これで始めることができます:http: //msdn.microsoft.com/en-us/library/bb677290.aspx

于 2012-07-05T02:40:28.010 に答える