0

我有一个 db 表,它仅由一列当前 ids(键)和第二个 columnm 及其以前的 ids 组成。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 回答