Вероятно, вам не хватает данных, потому что вы использовали inner join
. Это проблематично c для случаев, когда прародителя нет в таблице, например:
- для
CommentID = 1036
нам не дают прародителя / родителя при извлечении данных - для любого комментария на уровне 1 иерархии (т.е. Parent = 0)
Использование left join
должно исправить это.
Используемые данные
declare @target table (
CommentID int
,PostID int
,Comment varchar(200)
,ParentCommentId int
);
insert into @target
values
(1036, 32, 'Que?', 1033)
,(1037, 32, 'What up mane', 1035)
,(1038, 32, 'Hi', 0)
,(1039, 32, 'Can you see me?', 1038)
,(1040, 32, 'Test', 1039)
,(1041, 32, 'T', 1038)
,(1042, 32, 'Yoooo', 0)
,(1043, 32, 'Test?', 1042)
,(1044, 32, 'Test 1', 1039)
,(1045, 32, 'Test 2', 1039)
;
Получение иерархии
Можно построить простую таблицу иерархии, показывающую три уровня
select
GrandParentCommentID = isnull(b.ParentCommentID, 0)
,a.ParentCommentID
,a.CommentID
from @target as a
left join @target as b on a.ParentCommentId = b.CommentID
Полный ответ
with Hierarchy as (
select
GrandParentCommentID = b.CommentID
,a.ParentCommentID
,a.CommentID
from @target as a
inner join @target as b on a.ParentCommentId = b.CommentID
)
select
hier.GrandParentCommentID
,hier.ParentCommentID
,hier.CommentID
,details.Comment
from Hierarchy as hier
inner join @target as details on details.CommentID = hier.CommentID
order by
hier.GrandParentCommentID
,hier.ParentCommentID
Результаты
Бонус
Если вы хотите получить уровень в виде столбца, вы можете использовать рекурсивный CTE, как показано ниже (я уверен, что есть лучшие способы):
;with Hierarchy as (
select
GrandParentCommentID = 0
,ParentCommentID = 0
,CommentID
,hier_level = 1
from @target where ParentCommentID = 0
union all
select
GrandParentCommentID = h.ParentCommentID
,t.ParentCommentID
,t.CommentID
,hierarchy_level = h.hier_level + 1
from Hierarchy as h
inner join @target as t on t.ParentCommentId = h.CommentID
)
select * from Hierarchy
Добавьте прабабушку для демонстрации:
insert into @target values (1045, 32, 'Test 2', 1039);
Результаты: