Вопрос Sql: Получение родительских строк, за которыми следуют дочерние строки - PullRequest
0 голосов
/ 22 октября 2009

id parent_id

1 0

2 0

3 2

4 0

5 1

6 0

Мне нужен запрос, который вернет родительские строки (parent_id = 0), за которыми следуют его дочерние строки

первый родитель

все дети первого родителя

второй родитель

все дети второго родителя

третий родитель

четвертый родитель

Ожидаемый результат: упорядочено по id

id parent_id

10 (первый родитель)

5 1 (все дети первого родителя)

2 0 второй родитель

3 2 (все дети второго родителя)

4 0 третий родитель

6 0 четвертый родитель

Я могу использовать союз родителей, за которым следуют все дети Но это дает мне сначала родителей, потом детей. Мне нужен родитель и сразу его дети.

Кто-нибудь может помочь?

Ответы [ 3 ]

3 голосов
/ 20 февраля 2010

Вот пример решения, использующего объединение с предложением 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
1 голос
/ 22 октября 2009

Насколько я знаю, вы не можете сделать это с помощью одного оператора SQL, если все, что вы храните, это родительский идентификатор. Если вам нужно быстро получить дерево данных, вам следует рассмотреть возможность хранения прохождения предварительного заказа. Это проще, чем кажется, и это очень хорошо описано здесь: http://articles.sitepoint.com/article/hierarchical-data-database

0 голосов
/ 20 февраля 2010

Для этого вы использовали бы рекурсивный 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 уровней. Если это вас беспокоит, вам нужно отрегулировать количество нулей в разных местах.

Возможно, есть лучшие способы, но этот работает.

...