Вопрос Sql: Получение родительских строк, за которыми следуют дочерние строки
-
05-07-2019 - |
Вопрос
id parent_id
1 0
2 0
3 2
4 0
5 1
6 0
Мне нужен запрос, который будет возвращать родительские строки (parent_id = 0), за которыми следуют его дочерние строки
первый родитель
все дети первого родителя
второй родитель
все дети второго родителя
третий родитель
четвертый родитель
Ожидаемый результат: упорядочено по id
id parent_id
1 0 (первый родитель)
5 1 (все дети первого родителя)
2 0 второй родитель
3 2 (все дети второго родителя)
4 0 третий родитель
6 0 четвертый родитель
Я могу использовать союз родителей, за которым следуют все дети Но это дает мне сначала родителей, потом детей. Мне нужен родитель и сразу его дети.
Кто-нибудь может помочь?
Решение
Для этого вы бы использовали рекурсивный CTE:
WITH r AS
(SELECT id,
NULL AS parent_id,
CAST(right('000' + CAST(row_number()
OVER (table.id) AS varchar), 3) AS varchar(50))
FROM table WHERE parent IS NULL
UNION ALL
SELECT table.id, table.parent_id,
CAST(r.ord + right('000' + CAST(row_number()
OVER (ORDER BY table.id) AS varchar), 3) AS varchar(50))
FROM r JOIN table
ON table.parent = r.id)
SELECT id
FROM r
ORDER BY left(ord + '000000000000000000000000000000000', 36)
Обратите внимание, что эта конкретная версия сломается, если какой-либо идентификатор имеет значение больше 999, и сломается, если у вас более 12 уровней. Если это вас беспокоит, вам нужно настроить количество нулей в разных местах.
Возможно, есть лучшие способы, но этот работает.
Другие советы
Вот пример решения, использующего объединение с предложением order by (хотя оно не будет работать для глубокого вложения).
SELECT p.id,
p.parent_id,
p.name,
p.id AS sequence
FROM topics AS p
WHERE p.parent_id = 0
UNION
SELECT t.id,
t.parent_id,
t.name,
t.parent_id AS sequence
FROM topics AS t
WHERE t.parent_id <> 0
ORDER BY sequence, parent_id, name
Насколько я знаю, вы не можете сделать это с помощью одного оператора SQL, если все, что вы храните, это родительский идентификатор. Если вам нужно быстро получить дерево данных, вам следует рассмотреть возможность хранения прохождения предварительного заказа. Это проще, чем кажется, и это очень хорошо описано здесь: http: //articles.sitepoint. ком / статьи / иерархические-данные базы данные