2015-03-28 2 views
3

enter image description hereОтображение данных в виде дерева семьи с условием, где

Я хочу, чтобы отобразить данные в генеалогическом древе. Я могу легко использовать следующий запрос. Я столкнулся с проблемой, когда состояние города. Если я ищу город paris, тогда он отобразит только те данные, которые относятся к paris, но я хочу отобразить те данные, которые имеют головку семьи, paris. (если глава семьи принадлежит paris, тогда отобразите всех детей головного дома. Не нужно, чтобы ребенок был из Парижа). -1 является корневым уровень головы

; WITH CTE 
AS ( 
    SELECT ROW_NUMBER() OVER (ORDER BY c.ContactId) as MCID , 1 as CID 
    ,c.contactId 
    FROM ContactDetail c where c.FamilyHeadId = -1 
    UNION ALL 
    SELECT cte.MCID as MCID , 
    CONVERT(INT,(
        CONVERT(VARCHAR(10),CTE.CID) + 
        CONVERT(VARCHAR(10),ROW_NUMBER() OVER (ORDER BY p.ContactId)) 
       ) 
      ) AS CID 

    ,p.contactId 
    FROM ContactDetail p INNER JOIN cte ON p.FamilyHeadId = CTE.ContactId 

) 

select * from CTE 
inner join ContactDetail b on cte.contactid = b.contactid 
order by mcid,CID 

ответ

2

Вы можете перемещать фильтр на «Париже» в первоначальном запрос якорного КТРА (в то поиск главы семьи также будет ограничен городами). Однако этот предикат не должен повторяться в рекурсивном запросе после UNION в CTE (поскольку для ограничения детей не требуется). Я предполагал, столбец CityName на ContactDetail но предположительно фактическая модель имеет нормализованное отношение к таблице города или такому:

; WITH CTE 
AS ( 
    SELECT ROW_NUMBER() OVER (ORDER BY c.ContactId) as MCID, 1 as CID, c.contactId 
    FROM ContactDetail c 
    WHERE c.FamilyHeadId = -1 AND c.City = 'Paris' 

    UNION ALL 

    SELECT cte.MCID as MCID, 
     CONVERT(INT, (CONVERT(VARCHAR(10),CTE.CID) + 
      CONVERT(VARCHAR(10),ROW_NUMBER() OVER (ORDER BY p.ContactId)))) AS CID 
     ,p.contactId 
    FROM ContactDetail p 
     INNER JOIN cte ON p.FamilyHeadId = CTE.ContactId 

) 
SELECT * FROM CTE 
INNER JOIN ContactDetail b on cte.contactid = b.contactid 
order by mcid, CID; 

SqlFiddle here

Обратите внимание, что вы можете избежать окончательного присоединиться во внешнем запросе обратно в ту же таблицу, испуская все необходимые поля из запросов 2 КТР в соответствии с настоящим updated SqlFiddle

+0

У меня есть только один стол. пожалуйста, напишите ваш запрос в деталях. –

+0

Я расширил полный запрос и добавил [SqlFiddle] (http://sqlfiddle.com/#!6/ce9d0/1). В конечном итоге у All ContactId есть FamilyHeadId 1 в качестве предка (который является единственным FamHead в Париже), за исключением 6,7 и 14. В стороне вы можете посмотреть [Иерархические данные] (https://msdn.microsoft. com/en-us/library/bb677173.aspx? f = 255 и MSPPError = -2147217396) в качестве альтернативного решения. – StuartLC

+0

Thanx sir ваш запрос работает нормально, когда глава корневого уровня (-1) находится из paris. но как можно будет отображать, когда основная глава семьи не из Парижа, а подглавная - от paris, тогда она должна отображаться в данных от дочернего элемента до конца. –

-1
select * from contactdetail where city = lower('paris') 
    union 
    select contactId, FamilyHeadId, Name, City from contactdetail cross apply (
     select contactid as pcontactid, city as pcity from contactdetail where familyheadid = -1 
    ) parentdata 
     where pcity = lower('paris') and pcontactid = familyheadid 
+0

Результат не отображается в генеалогическом древе –

+0

PLZ использовать мой запрос @sql end и посмотреть результаты сначала на sql end –

+0

Я думаю, вы хотите разделить родителей вместе с их ребенком. Я прав? –

0

фактически таблицы переменных может быть более лучше курсора, так что я использовать что PLZ проверить этот запрос Он должен помочь вам.

declare @allheadCount int, @allheadCounttree int , @contactId int 
declare @city varchar(50), @name varchar(50) 

set @allheadCounttree =0 

DECLARE @familyTree TABLE 
(
familyId int IDENTITY(1,1), 
contactId int , 
familyHeadId int, 
Name varchar(50) NOT NULL, 
city varchar(50) NOT NULL, 
headcity varchar(50) NOT NULL 
) 

select @allheadCount = count(contactid) from contactdetail where familyheadid = -1 

WHILE @allheadCount <> @allheadCounttree 
BEGIN 

    select top 1 @contactid = contactId, @name=name, @city=city from contactdetail where familyheadid = -1 and contactid not in (select distinct contactid from @familytree) 

    insert into @familyTree (contactid,familyheadid,name,city,headcity) Values (@contactId,-1,@name,@city,@city) 

    insert into @familyTree (contactid,familyheadid,name,city,headcity) 
    select contactid,@contactId,name,city,@city from contactdetail where familyheadid = @contactid 

    select @allheadCounttree = count(contactid) from @familyTree where familyheadid = -1 

END 

select * from @familyTree where city = lower('Paris') or headcity = lower('paris') order by familyid 
Смежные вопросы