Oracle
 sql >> Database >  >> RDS >> Oracle

Richiesto ricorsione su database per ottenere risultati gerarchici utilizzando Hibernate - Java

Non eseguire la ricerca ricorsiva in Java. Ciò non si ridimensionerà perché invierai lotti di query al database. Usa una (singola) query ricorsiva direttamente sul database che funzionerà e scalerà molto meglio.

Non hai specificato il tuo DBMS ma le query ricorsive sono supportate da tutti i database moderni. Quanto segue è ANSI SQL standard:

with recursive ancestry as (
   select child, parent, 1 as level
   from users
   where parent = 'Grandfather' -- this is the one who logs in
   union all
   select c.child, c.parent, p.level + 1
   from users c
     join ancestry p on p.child = c.parent
)
select child, level
from ancestry
order by level desc;

Esempio:http://rextester.com/TJGTJ95905

Modifica dopo che il database reale è stato divulgato.

In Oracle hai due modi per farlo.

Il modo "tradizionale" consiste nell'usare connect by che è una forma molto più compatta di una query ricorsiva rispetto a ciò che lo standard SQL ha prodotto:

select child, level
from users
start with parent = 'Grandfather'
connect by prior child = parent
order by level desc;

Potresti utilizzare anche un'espressione di tabella comune in Oracle. Tuttavia, anche se lo standard SQL richiede la parola chiave recursive per essere obbligatorio, Oracle ha scelto di ignorare quella parte dello standard, quindi è necessario rimuoverlo. LEVEL è una pseudo-colonna in Oracle che può essere utilizzata solo insieme a connect by quindi questo non può essere utilizzato nella soluzione CTE:

with ancestry (child, parent, lvl) as (
   select child, parent, 1 as lvl
   from users
   where parent = 'Grandfather'
   union all
   select c.child, c.parent, p.lvl + 1
   from users c
     join ancestry p on p.child = c.parent
)
select child, lvl
from ancestry
order by lvl desc