В простом наборе данных, который представляет собой иерархию с конечным числом небольших уровней, вы можете сделать это путем простого самостоятельного присоединения. если ваш механизм базы данных не поддерживает CTE
s или вам нужно было упростить обслуживание запросов.
Настройка с использованием табличной переменной
DECLARE @table table (
id int,
name varchar(10),
[date] date,
parentid int
)
insert into @table values
(1, 'AAA', '9/7/2020', 1),
(2, 'BBB', '9/8/2020', 2),
(3, 'CCC', '9/8/2020', 3),
(4, 'DDD', '9/8/2020', 4),
(5, 'EEE', '9/8/2020', 2),
(6, 'FFF', '9/8/2020', 1),
(7, 'GGG', '9/8/2020', 5),
(8, 'HHH', '9/8/2020', 3),
(9, 'III', '9/8/2020', 4),
(10, 'JJJ', '9/8/2020', 10)
Запрос из @table
с 3 уровнями глубины
SELECT child.id, child.name, child.[date], child.parentId
FROM @table child
LEFT OUTER JOIN @table parent on child.parentid = parent.id
ORDER BY parent.parentid, child.parentid, child.id
Если в вашей структуре данных есть нули, указывающие на отсутствие родителя, то этот запрос снова может быть более эффективным, но нам нужно COALESCE
идентификаторов:
SELECT child.id, child.name, child.[date], child.parentId
FROM @table child
LEFT OUTER JOIN @table parent on child.parentid = parent.id
order by COALESCE(parent.parentid,child.parentid,child.Id), IsNull(child.parentid,child.Id), child.id
Наконец, для поддержки каждого дополнительного уровня рекурсии добавьте еще join , в конечном итоге вам понадобится n-2
соединений, где n
- максимальное количество уровней, которые будут поддерживать ваши данные, следующие поддерживают 4 уровня:
SELECT child.id, child.name, child.[date], child.parentId
FROM @table child
LEFT OUTER JOIN @table parent on child.parentid = parent.id
LEFT OUTER JOIN @table grandparent on parent.parentid = grandparent.id
order by COALESCE(grandparent.parentId, parent.parentid,child.parentid,child.Id), COALESCE(parent.parentid,child.parentid,child.Id), IsNull(child.parentid,child.Id), child.id