SQL 服务器:运行 为没有游标或函数的每条记录单独的 CTE
SQL Server: Run separate CTE for each record without cursor or function
给定 table A 有一个列 LocationID
和许多记录,
是否可以完全 运行 每条记录的 CTE,而不使用游标(while fetch 循环)或函数(通过交叉应用)?
我不能 运行 来自 table A 的 CTE,因为 CTE 将深入父子层次结构 table(ParentID,ChildID)以找到所有后代特定类型的,对于 table A 的每个 LocationID。似乎如果我使用 table A 进行 CTE,它将混合 table A 中所有 LocationID 的子项。
基本上我需要单独运行一个CTE,对于table A的每个LocationID,并放入一个table带有LocationID和ChildID列(LocationID来自table A 和 ChildID 都是通过 CTE 找到的特定类型的后代。
这是您的基本布局。
;with CTE AS
(
select .......
)
select *
from CTE
cross apply (select distinct Location from TableA) a
where CTE.Location=a.Location
一些示例数据和预期结果将提供更好的答案。
你可以这样做:
Declare @LocationID As Int
Select
LocationID
, 0 as Processed
Into #Temp_Table
From TableA
While Exists (Select Top 1 1 From #Temp_Table Where Processed = 0)
Begin
Select Top 1 @LocationID = LocationID
From #Temp_Table
Where Processed = 0
Order By LocationID
/* Do your processing here */
Update #Temp_Table Set
Processed = 0
Where LocationID = @LocationID
End
它仍然是 RBAR,但(至少在我的环境中)它比游标快得多。
我找到了解决办法。我只需要保留原始的 LocationID
作为参考,然后在 CTE 结果中,当它深入列表时将包括所有可能的记录,我应用我需要的过滤器。是的,所有记录都混合在结果中,但是因为保留了对来源 table 的 LocationID 的引用(如 OriginalParentID
),我仍然能够检索到它。
;WITH CTE AS
(
--Original list of parents
SELECT a.LocationID AS OriginalParentID, l.ParentID, l.ChildID, l.ChildType
FROM TableA a
INNER JOIN tblLocationHierarchy l ON l.ParentID = a.LocationID
UNION ALL
--Getting all descendants of the original list of parents
SELECT CTE.OriginalParentID, l.ParentID, l.ChildID, l.ChildType
FROM tblLocationHierarchy l
INNER JOIN CTE ON CTE.ChildID = l.ParentID
)
SELECT OriginalParentID, ChildID
FROM CTE
--Filtering is done here
WHERE ChildType = ...
给定 table A 有一个列 LocationID
和许多记录,
是否可以完全 运行 每条记录的 CTE,而不使用游标(while fetch 循环)或函数(通过交叉应用)?
我不能 运行 来自 table A 的 CTE,因为 CTE 将深入父子层次结构 table(ParentID,ChildID)以找到所有后代特定类型的,对于 table A 的每个 LocationID。似乎如果我使用 table A 进行 CTE,它将混合 table A 中所有 LocationID 的子项。
基本上我需要单独运行一个CTE,对于table A的每个LocationID,并放入一个table带有LocationID和ChildID列(LocationID来自table A 和 ChildID 都是通过 CTE 找到的特定类型的后代。
这是您的基本布局。
;with CTE AS
(
select .......
)
select *
from CTE
cross apply (select distinct Location from TableA) a
where CTE.Location=a.Location
一些示例数据和预期结果将提供更好的答案。
你可以这样做:
Declare @LocationID As Int
Select
LocationID
, 0 as Processed
Into #Temp_Table
From TableA
While Exists (Select Top 1 1 From #Temp_Table Where Processed = 0)
Begin
Select Top 1 @LocationID = LocationID
From #Temp_Table
Where Processed = 0
Order By LocationID
/* Do your processing here */
Update #Temp_Table Set
Processed = 0
Where LocationID = @LocationID
End
它仍然是 RBAR,但(至少在我的环境中)它比游标快得多。
我找到了解决办法。我只需要保留原始的 LocationID
作为参考,然后在 CTE 结果中,当它深入列表时将包括所有可能的记录,我应用我需要的过滤器。是的,所有记录都混合在结果中,但是因为保留了对来源 table 的 LocationID 的引用(如 OriginalParentID
),我仍然能够检索到它。
;WITH CTE AS
(
--Original list of parents
SELECT a.LocationID AS OriginalParentID, l.ParentID, l.ChildID, l.ChildType
FROM TableA a
INNER JOIN tblLocationHierarchy l ON l.ParentID = a.LocationID
UNION ALL
--Getting all descendants of the original list of parents
SELECT CTE.OriginalParentID, l.ParentID, l.ChildID, l.ChildType
FROM tblLocationHierarchy l
INNER JOIN CTE ON CTE.ChildID = l.ParentID
)
SELECT OriginalParentID, ChildID
FROM CTE
--Filtering is done here
WHERE ChildType = ...