sql >> Databáze >  >> RDS >> PostgreSQL

Rekurzivní dotaz používaný pro tranzitivní uzávěr

Zjednodušit můžete na několika místech (za předpokladu, že acct_id a parent_id 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;
  • Sloupce acct_id , depth , cycle jsou ve vašem dotazu jen šumy.
  • WHERE podmínka musí ukončit rekurzi o jeden krok dříve, před duplicitní záznam z horního uzlu je ve výsledku. To bylo ve vašem originálu „neza sebou“.

Zbytek je formátování.

Pokud víte jediný možný kruh ve vašem grafu je autoreference, můžeme to mít levnější:

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.

U datových typů s modifikátorem (jako varchar(5) by mohly nastat problémy (alespoň do pg v9.4) ), protože zřetězení pole ztrácí modifikátor, ale rCTE trvá na tom, aby se typy přesně shodovaly:

  • Překvapivé výsledky pro datové typy s modifikátorem typu


  1. Migrace z MySQL na PostgreSQL – co byste měli vědět

  2. Jak zkopírovat data velké tabulky do jiné tabulky v SQL Server

  3. Jak vypočítat věk od data narození v SQL

  4. Připojte Javu k databázi MySQL