SQL Server:对没有游标或函数的每条记录运行单独的CTE

时间:2018-10-29 19:22:48

标签: sql-server common-table-expression sql-function cross-apply

为表A提供一个列LocationID和许多记录,

是否可以为每个记录完全运行CTE,而无需使用游标(在获取循环中)或函数(通过交叉应用)?

我无法从表A运行CTE,因为CTE将深入父子层次结构表(ParentID,ChildID)以查找表A的每个LocationID特定类型的所有后代。如果我使用表A进行CTE,它将混合表A中所有LocationID的子代。

基本上,我需要为表A的每个LocationID分别运行CTE,并将其放入具有LocationID和ChildID列的表中(LocationID是表A中的那些,而ChildID都是通过CTE找到的特定类型的后代)

3 个答案:

答案 0 :(得分:0)

这是您的基本布局。

;with CTE AS
(
   select .......
)

select *
from CTE
cross apply (select distinct Location from TableA) a
where CTE.Location=a.Location

一些样本数据和预期结果将提供更好的答案。

答案 1 :(得分:0)

您可以执行以下操作:

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,但是(至少在我的环境中)它比游标更快。

答案 2 :(得分:0)

我能够找到解决方案。我只需要保留原始的LocationID作为参考,然后在CTE结果中(其中包括所有可能的记录,因为它深入列表中)将应用所需的过滤器。是的,结果中混合了所有记录,但是因为保留了对原始表的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 = ...