Domanda SQL: ottenere le righe principali seguite da righe secondarie
-
05-07-2019 - |
Domanda
id parent_id
1 0
2 0
3 2
4 0
5 1
6 0
Ho bisogno di una query che restituisca le righe principali (parent_id = 0) seguite dalle sue righe secondarie
primo genitore
tutti i figli del primo genitore
secondo genitore
tutti i figli del secondo genitore
terzo genitore
quarto genitore
Risultato atteso: ordinato per ID
id parent_id
1 0 (primo genitore)
5 1 (tutti i figli del primo genitore)
2 0 secondo genitore
3 2 (tutti i figli del secondo genitore)
4 0 terzo genitore
6 0 quarto genitore
Posso usare l'unione dei genitori seguita da tutti i bambini Ma questo mi dà prima i genitori e poi i bambini. Ho bisogno di un genitore e immediatamente dei suoi figli.
Chiunque può aiutare?
Soluzione
Dovresti usare un CTE ricorsivo per questo:
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)
Nota che questa particolare versione si interromperà se qualsiasi ID ha un valore maggiore di 999 e si interromperà se hai più di 12 livelli. Se questo è un problema per te, devi regolare il numero di zero nei vari punti.
Potrebbero esserci modi migliori, ma questo funziona.
Altri suggerimenti
Ecco una soluzione di esempio che utilizza un'unione con una clausola order by (non funzionerà per l'annidamento profondo).
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
Per quanto ne so, non puoi farlo con una singola istruzione SQL se tutto ciò che stai memorizzando è l'id genitore. Se devi recuperare rapidamente l'albero dei dati, dovrai considerare di memorizzare un attraversamento del preordine. È più facile di quanto sembri ed è molto ben descritto qui: http: //articles.sitepoint. com / articolo / gerarchico--database dati