私は私に頭痛を与えているこの問題を抱えています...
たとえば、数千行のテーブルがあり、テーブルの構造は親->子の関係で構成されているとします。
関係は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 があります。
これはそれを行うはずです:
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のヘルプについては このリンク を確認してください...
これがうまくいくことを願っています!
;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