sql >> Database >  >> RDS >> PostgreSQL

Recursieve zoekopdracht gebruikt voor transitieve afsluiting

U kunt op verschillende plaatsen vereenvoudigen (ervan uitgaande dat acct_id en parent_id zijn NOT NULL ):

WITH RECURSIVE search_graph AS (
   SELECT parent_id, ARRAY[acct_id] AS path
   FROM   account

   UNION  ALL
   SELECT g.parent_id, sg.path || g.acct_id
   FROM   search_graph sg
   JOIN   account g ON g.acct_id = sg.parent_id 
   WHERE  g.acct_id <> ALL(sg.path)
   )
SELECT path[1] AS child
     , path[array_upper(path,1)] AS parent
     , path
FROM   search_graph
ORDER  BY path;
  • De kolommen acct_id , depth , cycle zijn slechts ruis in uw zoekopdracht.
  • De WHERE voorwaarde moet de recursie een stap eerder verlaten, voor de dubbele invoer van het bovenste knooppunt staat in het resultaat. Dat was een "off-by-one" in je origineel.

De rest is formatteren.

Als je weet de enige mogelijke cirkel in je grafiek is een zelfreferentie, die kunnen we goedkoper hebben:

WITH RECURSIVE search_graph AS (
   SELECT parent_id, ARRAY[acct_id] AS path, acct_id <> parent_id AS keep_going
   FROM   account

   UNION  ALL
   SELECT g.parent_id, sg.path || g.acct_id, g.acct_id <> g.parent_id
   FROM   search_graph sg
   JOIN   account g ON g.acct_id = sg.parent_id 
   WHERE  sg.keep_going
)
SELECT path[1] AS child
     , path[array_upper(path,1)] AS parent
     , path
FROM   search_graph
ORDER  BY path;

SQL Fiddle.

Merk op dat er problemen zouden zijn (tenminste tot pg v9.4) voor datatypes met een modifier (zoals varchar(5) ) omdat array-aaneenschakeling de modifier verliest, maar de rCTE dringt erop aan dat typen exact overeenkomen:

  • Verrassende resultaten voor gegevenstypen met typemodifier


  1. Selecteer datatype van het veld in postgres

  2. Selecteer laatste rij in MySQL

  3. Geen geschikte driver gevonden voor jdbc:postgresql://192.168.1.8:5432/NexentaSearch

  4. Wat doet de methode Statement.setFetchSize(nSize) echt in het SQL Server JDBC-stuurprogramma?