2013-05-22 1 views
1

Там в таблице, которая описывает иерархию объектов и их тип:Дерево MSSQL CTE с фильтром как?

DECLARE @TTable TABLE 
(
ID int 
,Higher int -- for some reason this is how ID_PARENT named 
,[Type] int 
) 

нужно выбрать поддерево с ветвями, содержащими только узлами определенного [Type]. Так как я новичок в SQL вообще и КТР я сделал это первым найти все ветви, которые содержат объекты определенного типа снизу вверх:

;WITH c 
AS 
(
SELECT 
    ID 
    ,Higher 
    ,[Type] 
FROM 
    dbo.EnObj 
WHERE Type = 40 

UNION ALL 

SELECT 
    t.ID 
    ,t.Higher 
    ,t.Type 
FROM 
    dbo.EnObj T 
INNER JOIN c ON t.ID = c.Higher 
) 

Затем выбрал уникальные записи в табличную переменную:

INSERT @TTable 
SELECT DISTINCT 
c.ID 
,c.Higher 
,c.Type 
,c.Name 
,c.Voltage 
FROM c 

а затем построил иерархию по КТР с сортировкой сверху вниз:

;WITH CTE AS (
    SELECT 
    ID 
    ,Higher 
    ,[Type] 
,CAST(ID AS VARCHAR(128)) AS Sort 
FROM  
    @TTable 
WHERE 
    Higher IS NULL 
UNION ALL 
SELECT 
    N.ID 
    ,N.Higher 
    ,N.[Type] 
    ,CAST(P.Sort + '/' + CAST(N.ID AS VARCHAR) AS VARCHAR(128)) 
FROM  
    @TTable N 
INNER JOIN CTE AS P ON P.ID = N.Higher 
) 
SELECT 
    ID 
    ,Higher 
    ,[Type] 
    ,Sort 
FROM CTE 
ORDER BY Sort 

Это работает, но мне интересно, если есть способ, чтобы оптимизировать этот запрос, как с помощью одного КТР я вместо двух или иметь фильтр в CTE.

+0

Я думаю, что последний запрос очень приятно. – Devart

+0

С уважением, этот парень: [link] (http://beyondrelational.com/modules/2/blogs/28/posts/10486/recursive-cte-and-ordering-of-the-hierarchical-result.aspx) – user1699353

+0

Вы хотите получить иерархию определенного [типа] ниже определенного [Id]? Или все возможные деревья с определенным [типом]? –

ответ

1
with Hierachy 
as 
(
    select ID, Higher, Type from EnObj 
     WHERE Type = 40 -- Whatever your search criteria 

     union all 
    select EnObj.ID, EnObj.Higher ,EnObj.Type from EnObj  
    inner join Hierachy 
    on tblOrgLevel.Higher = Hierachy.ID 
) 
select * from Hierachy --where ID <> 40 

Другое решение

WITH DirectReports 
AS 
(
    SELECT parentid, id, Title, 0 AS EmployeeLevel 
    FROM dbo.tblOrgLevel 
    WHERE ISNULL(parentid ,0) = 0 and FKAgencyID = 58 
    UNION ALL 
    SELECT e.parentid, e.id, e.Title, EmployeeLevel + 1 
    FROM dbo.tblOrgLevel AS e 
     INNER JOIN DirectReports AS d 
     ON e.parentid= d.id 
) 
SELECT * 
FROM DirectReports 
ORDER BY parentid; 
GO 

Вы можете спросить у меня дополнительные пояснения, а некоторые модификации

Смежные вопросы