Вопрос Sql: Получение родительских строк, за которыми следуют дочерние строки

StackOverflow https://stackoverflow.com/questions/1604537

  •  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. ком / статьи / иерархические-данные базы данные

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top