我有这个让我头疼的问题......
说,我有一个包含数千行的表格,表格的结构由父母组成 - >孩子的关系。
这种关系可以达到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
我们有一个进程遍历整个表以获取关系并保存“levels”列,这个过程非常慢(因为循环)并且我尝试了一些cte来获得关系但是失败了miserabily。
到目前为止,我已经尝试了这个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,谢谢!
答案 0 :(得分:36)
这应该这样做:
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。
另外,查看this link以获取有关CTE的帮助......他们绝对不错:
希望这可以解决问题!
答案 1 :(得分:2)
;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