22

我有这个让我头疼的问题...

比如说,我有一个包含数千行的表,并且表的结构包含父-> 子关系。

关系可以上升到 6 个级别。这是表结构的示例:

ProductId | ParentId | Levels
1174           0        1174
311           1174      311, 1174
1186          311       1186, 311, 1174
448           1186      448, 1186, 311, 1174
3365          448       3365, 448, 1186, 311, 1174

我们有一个循环遍历整个表以获取关系并保存“级别”列的过程,这个过程真的很慢(因为循环),我已经尝试使用一些 cte 来获取关系,但不幸失败了。

到目前为止,我已经尝试过这个 cte,但它并没有达到我希望的效果,而且,它似乎在复制行......

;With Parents(ProductId, ParentId, Levels)
As(
  Select ProductId, ParentId, Levels
  From Products
  Where ParentId = 0 
  Union All
  Select p.ProductId, p.ParentId, p.Levels
  From Products p
  Join Parents cte On cte.ProductId = p.ParentId
)
Select *
From Parents

正如我之前提到的,我们有一个循环表格的过程,它完成了它的工作,但它可能需要长达 30 分钟,我的问题是有没有更好的方法来做到这一点?我知道 CTE 允许我这样做,但我很烂,而且,应该在表格上计算和更新级别列,这可能吗?

这是一个Sqlfiddle,以防有人可以提供帮助,谢谢!

4

2 回答 2

51

这应该这样做:

WITH MyTest as
(
  SELECT P.ProductID, P.ParentID, CAST(P.ProductID AS VarChar(Max)) as Level
  FROM Products P
  WHERE P.ParentID = 0

  UNION ALL

  SELECT P1.ProductID, P1.ParentID, CAST(P1.ProductID AS VarChar(Max)) + ', ' + M.Level
  FROM Products P1  
  INNER JOIN MyTest M
  ON M.ProductID = P1.ParentID
 )
SELECT * From MyTest

这是更新的SQL Fiddle

此外,请查看此链接以获取有关 CTE 的帮助......他们绝对很高兴知道:

希望这能解决问题!

于 2013-11-11T20:22:24.233 回答
3
;With Parents(ProductId, ParentId, Level, levels)
As(
  Select ProductId, ParentId, 0, 
     cast(ltrim(str(productId,8,0)) as varchar(max))
  From Products
  Where ParentId = 0 
  Union All
  Select p.ProductId, p.ParentId, 
      par.Level + 1,
      cast( levels + ', ' + ltrim(str(productId,8,0)) as varchar(max))
  From Products p
     Join Parents par
        On par.ProductId = p.ParentId
  )
  Select * From Parents
  Order By Level
于 2013-11-11T19:45:43.103 回答