SQL Server – список родительских записей в иерархическом порядке
У меня есть таблица, которая используется для построения древовидной структуры элементов меню. Пример содержимого этой таблицы приведен ниже:
Parent Child ------ ------ 190 192 192 180 180 185 185 184 190 191 191 197 197 200
Мне нужен запрос, который предоставит мне список родительских записей с разделителями-запятыми в порядке их появления в иерархии, включая дочерний идентификатор, например:
- Учитывая ребенка id 184, он должен вернуть 190, 192, 180, 185, 184
- Учитывая ребенка id 200, он должен вернуть 190, 191, 197, 200
- Объединить строки родительского ребенка - TSQL
- Вставка в родительские-дочерние таблицы в SQL Server
- Проблема с отношениями родитель-ребенок в Sql-Server
- Отношение родительского ребенка в SQL Server
- TSQL Cascade delete для дочерних записей?
- Поиск неизвестных сторонников XML с использованием SQL
- Отображаются многоуровневые категории продуктов с помощью asp.net и sql-сервера?
- Обновление поля родительской записи с использованием данных записи ребенка (та же таблица)
- Как выбрать одну родительскую строку и дополнительные строки для своих детей без UNION?
- Как создать запрос из родительской иерархической таблицы
- Как преобразовать вертикальную таблицу в горизонтальную таблицу?
- Родительский родитель SQL Server (родитель видит все)?
- Нужна целая цепочка Ребенка конкретной родительской записи на SQL-сервере
Я использовал табличную переменную для демонстрации. Чтобы использовать стандартную таблицу, удалите декларацию @tempTable
и вставьте инструкции. Затем замените ссылки @tempTable
на имя таблицы.
declare @childId int set @childId = 184 declare @tempTable table(parent int, child int) insert into @tempTable values(190, 192) insert into @tempTable values(192, 180) insert into @tempTable values(180, 185) insert into @tempTable values(185, 184) insert into @tempTable values(190, 191) insert into @tempTable values(191, 197) insert into @tempTable values(197, 200) declare @currentItem int set @currentItem = @childId declare @output varchar(max) set @output = cast(@currentItem as varchar) while (exists(select 1 from @tempTable where child = @currentItem)) begin select @currentItem = parent from @tempTable where child = @currentItem set @output = cast(@currentItem as varchar) + ', ' + @output end select @output
Пример вывода:
За 184: 190, 192, 180, 165, 184
Для 200: 190, 191, 197, 200
Вот…
Declare @data Table ( Parent int, Child int ) insert into @data values (190, 192), (192, 180), (180, 185), (185, 184), (190, 191), (191, 197), (197, 200) Declare @Id as Int = 184 /* CompleteData - query produce following output ID ParentId ----------- ----------- 180 192 184 185 185 180 190 NULL -- we discoverd this missing data 191 190 192 190 197 191 200 197 ChildHierarchyData - query produce following ouput ID ParentID Level ----------- ----------- ----------- 184 185 0 185 180 1 180 192 2 192 190 3 190 NULL 4 Concatinated - query conact all ID from above result */ ;with CompleteData as ( Select Child ID, Parent ParentId from @data UNION Select Child.Parent Id, Parent.Parent ParentId From @data Child Left Outer Join @data Parent on Child.Parent = parent.Child WHERE parent.Parent IS NULL ), ChildHierarchyData(ID,ParentID, Level) as ( Select ID,ParentID, 0 as Level from CompleteData Where ID = @Id union all Select CompleteData.ID, CompleteData.ParentID, ChildHierarchyData.Level +1 from CompleteData INNER Join ChildHierarchyData on ChildHierarchyData.ParentID = CompleteData.ID ), Concatinated(result) as ( Select Cast((select Cast(ID as nvarchar) + ',' [data()] from ChildHierarchyData Order By Level Desc FOR XML Path('')) as Nvarchar(max)) ) select Left(result, len(result)-1) as Result from Concatinated
Если вам нужен список, разделенный запятыми, это легко сделать с рекурсивным cte:
with cte as ( select t.Parent, 1 as Level, cast(t.Parent as nvarchar(max)) + ',' + cast(t.Child as nvarchar(max)) as Path from Table1 as t where t.Child = @Child union all select t.Parent, Level + 1 as Level, cast(t.Parent as nvarchar(max)) + ',' + c.Path as Path from Table1 as t inner join cte as c on c.Parent = t.Child ) select top 1 Path from cte order by Level desc
Демо-версия