我们有一个存储过程,在该过程中,我们使用while循环,每次将任何孩子的孩子作为父母的孩子插入。现在,此循环要花费11个小时以上才能完成。那么有人可以帮助我将while循环转换为CTE吗?哪个会减少执行时间?还有其他方法可以提高以下查询的性能吗?您可以从下面的链接中找到架构,如果访问下面的链接有任何问题,请使用下面的查询。
CREATE TABLE Temptbl (
ParentNumber Varchar(9) ,
ChildNumber Varchar(9)
);
DECLARE @lastupdate INTEGER
SET @lastupdate = 1
WHILE (@lastupdate > 0)
BEGIN
INSERT INTO Temptbl
SELECT DISTINCT
a.ParentNumber,
b.ChildNumber
FROM Temptbl a,
Temptbl b
WHERE a.ChildNumber = b.ParentNumber
AND NOT EXISTS (SELECT 1
FROM Temptbl c
WHERE c.ParentNumber = a.ParentNumber
AND c.ChildNumber = b.ChildNumber)
SET @lastupdate = @@ROWCOUNT
END
答案 0 :(得分:0)
尝试以下查询。可能会对您有帮助。
;with cte as (
SELECT DISTINCT
a.ParentNumber,
b.ChildNumber, ROW_NUMBER()over(order by a.ParentNumber) as RNO
FROM Temptbl a,
Temptbl b
WHERE a.ChildNumber = b.ParentNumber
AND NOT EXISTS (SELECT 1
FROM Temptbl c
WHERE c.ParentNumber = a.ParentNumber
AND c.ChildNumber = b.ChildNumber)
)
INSERT INTO Temptbl
select ParentNumber, ChildNumber from cte
where RNO>0
答案 1 :(得分:0)
如果需要递归,这里是一个版本,即如果给定A-> B,B-> C,C-> D,则期望A-> C和A-> D
DROP TABLE IF EXISTS Temptbl
CREATE TABLE Temptbl
(
ParentNumber VARCHAR(9),
ChildNumber VARCHAR(9)
)
INSERT INTO Temptbl (ParentNumber, ChildNumber)
VALUES ('a1','b1'), ('b1','c1'),
('a2','b2'), ('b2','c2'),
('a3','b3'), ('b3','c1'),
('c1','d1');
-- expect insert of
-- (a1, c1) via b1
-- (a1, d1) via b1 -> c1
-- (a2, c2) via b2
-- (a3, c1) via b3
-- (a3, d1) via b3 -> c1
-- (a3, d1) via b3 -> c1
-- (b3, d1) via c1
WITH Tree(ParentNumber,ChildNumber) AS
(
--Initialization
SELECT ParentNumber, ChildNumber
FROM Temptbl
UNION ALL
SELECT t1.ParentNumber,t2.ChildNumber AS ChildNumber
FROM Temptbl t1
INNER JOIN Temptbl t2 ON t1.ChildNumber = t2.ParentNumber
UNION ALL
--Recursive execution
SELECT Tree.ParentNumber,t.ChildNumber
FROM Temptbl t INNER JOIN Tree ON Tree.ChildNumber = t.ParentNumber
)
INSERT INTO Temptbl
(
ParentNumber,
ChildNumber
)
SELECT DISTINCT
Tree.ParentNumber,
Tree.ChildNumber
FROM tree
WHERE NOT EXISTS (SELECT * FROM Temptbl t WHERE t.ParentNumber = tree.ParentNumber AND t.ChildNumber = tree.ChildNumber)
OPTION (MAXRECURSION 5); -- change 5 to the maximum depth of hierarchy you need it to handle
SELECT * FROM dbo.Temptbl