我正在处理包含项目及其详细信息的表格。 该表包含ItemID以及" Alt_ItemID"它存储另一个可用于代替原始Item的ItemID。例如
ItemID,Item_Description,Alt_ItemID
ABC123,Square Brick,ABC456
ABC456,Almost Square Brick,null
因此,如果我们缺货,项目ABC123可以在其中使用项目ABC456。
这些关系可以继续,因此ABC456可以有一个替代的DEF123,可以用来代替ABC123或ABC456。 '级联'可以无限期地继续下去(某些项目的使用优先顺序中列出了20-30种替代方式)
我使用游标(我知道的很慢)循环遍历下面的表并编译一对多(全局,所以我可以看到它有多远)临时表显示&# 34;原"项目和所有可能的级联项目。问题是,目前的速度需要大约10个小时才能完成,所以我们不能在实时报告中使用它(并且由于Items表的流畅性质不适合定期存储)。 / p>
关于使用连接/ CTE的安排是否可以更快地完成任何想法?
NB。 " @AltItem<> @ PART_NUM"和" @AltItem<> ''"不幸的是,由于自我引用的错误数据和级联反应,这是必要的。而烦人的空白。
create table ##Alternatives (ItemID varchar(50), Alt_ItemID varchar(50))
Declare @ItemID AS Nvarchar(MAX)
DEclare @AltItem as nvarchar(max)
DECLARE Alternatives CURSOR FOR
SELECT ItemID
FROM DatabaseName.dbo.ItemTable
OPEN Alternatives
FETCH NEXT FROM Alternatives
INTO @ItemID
WHILE @@FETCH_STATUS = 0
BEGIN
select @AltItem = Alt_ItemID from DatabaseName.dbo.ItemTable where ItemID = @ItemID and Alt_ItemID <> @ItemID
while @AltItem is not null and @AltItem <> '' and @AltItem <> @ItemID
begin
insert into ##Alternatives values (@ItemID, Alt_ItemID)
select @AltItem = Alt_ItemID from DatabaseName.dbo.ItemTable
where ItemID = @AltItem and Alt_ItemID <> @AltItem and Alt_ItemID <> @ItemID
end
FETCH NEXT FROM Alternatives
INTO @ItemID
END
CLOSE Alternatives;
DEALLOCATE Alternatives;
select * from ##Alternatives
--drop table ##Alternatives
答案 0 :(得分:2)
这是使用递归CTE的答案:
<强>设置强>
CREATE TABLE #ItemTable
(
ItemID varchar(10) PRIMARY KEY,
Item_Description varchar(50),
Alt_ItemID varchar(10) NULL
)
INSERT INTO #ItemTable
VALUES ('ABC123', 'Square Brick', 'ABC456'),
('ABC456', 'Almost Square Brick', null),
('DEF123', 'Sphere', 'GHI789'),
('GHI789', 'Oval', 'XYZ123'),
('XYZ123', 'Circle', NULL)
公用表表达式查询
WITH CTE
AS
(
-- Find the top level item
SELECT ItemId As ParentItemId, ItemId, Item_Description, Alt_ItemId, 0 As Level
FROM #ItemTable IT1
WHERE NOT EXISTS (SELECT * FROM #ItemTable IT2 WHERE IT1.ItemID = IT2.Alt_ItemId)
UNION ALL
SELECT CTE.ParentItemId As ParentItemId, IT1.ItemId, IT1.Item_Description, IT1.Alt_ItemId, CTE.Level + 1 As Level
FROM #ItemTable IT1
INNER JOIN CTE
ON CTE.Alt_ItemId = IT1.ItemId
)
SELECT ParentItemId, ItemId, Item_Description
FROM CTE
WHERE CTE.LEvel > 0
ORDER By ParentItemId
<强>结果:强>
ParentItemId ItemId Item_Description
------------ ------ -------------------
ABC123 ABC456 Almost Square Brick
DEF123 GHI789 Oval
DEF123 XYZ123 Circle