SQL Server: запуск отдельной CTE для каждой записи без курсора или функции
Приведенная таблица А с колонкой LocationID
и много записей,
Можно ли полностью запустить CTE для каждой записи без использования курсора (во время цикла выборки) или функции (через перекрестное применение)?
Я не могу запустить CTE из таблицы A, потому что CTE углубится в иерархическую таблицу parent-child (ParentID, ChildID), чтобы найти всех потомков определенного типа для каждого LocationID таблицы A. Кажется, что если я сделать CTE, используя таблицу A, он будет смешивать дочерние элементы всех LocationID в таблице A.
По сути, мне нужно отдельно запустить CTE для каждого LocationID таблицы A и поместить в таблицу со столбцами LocationID и ChildID (LocationID - это те, что из таблицы A, а ChildID - это потомки определенного типа, найденного через CTE).
3 ответа
Я смог найти решение. Я просто должен был сохранить оригинал 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 = ...
Это ваш основной макет.
;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, но (по крайней мере, в моем окружении) это намного быстрее, чем курсор.