Pergunta SQL: Obtendo linhas pai seguido por linhas filho
-
05-07-2019 - |
Pergunta
id parent_id
1 0
2 0
3 2
4 0
5 1
6 0
Eu preciso de uma consulta que irá retornar as linhas parentais (parent_id = 0), seguida por suas linhas criança
primeiro pai
todas as crianças do primeiro pai
segundo pai
todas as crianças do segundo pai
terceiro pai
quarta pai
Resultado esperado: ordenados por id
id parent_id
1 0 (primeiro pais)
5 1 (todos os filhos do primeiro pai)
2 0 segundo pai
3 2 (todos os filhos de segundo pai)
4 0 terceira pai
6 0 quarto dos pais
Eu posso usar a união dos pais seguido por todos os criança Mas isso me dá aos pais primeiro e depois as crianças. Eu preciso pai e imediatamente as suas crianças.
Alguém pode ajudar?
Solução
Você usaria uma CTE recursiva para isso:
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)
Note que esta versão especial vai quebrar se houver ID tem um valor maior do que 999, e ele vai quebrar se você tem mais de 12 níveis. Se esta é uma preocupação para você, você precisa ajustar o número de zeros nos vários lugares.
Pode haver maneiras melhores, mas este funciona.
Outras dicas
Aqui é uma solução de exemplo, usando uma união com uma cláusula ORDER BY (isso não vai funcionar para o assentamento profundo embora).
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
Tanto quanto eu sei, você não pode fazer isso com uma única instrução SQL se tudo que você está armazenando é o id do pai. Se você precisar recuperar a árvore de dados rapidamente, você tem que considerar o armazenamento de um percurso pré-ordem. É mais fácil do que parece e é muito bem descrito aqui: http: //articles.sitepoint. com / artigo / hierárquica-data-base de dados