PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Zapytanie rekurencyjne używane do zamykania przechodniego

Możesz uprościć w kilku miejscach (zakładając, że acct_id i parent_idNOT 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;
  • Kolumny acct_id , depth , cycle to tylko szum w zapytaniu.
  • WHERE warunek musi wyjść z rekurencji o krok wcześniej, przed w wyniku znajduje się zduplikowany wpis z górnego węzła. W oryginale było to „przegranie”.

Reszta to formatowanie.

Jeśli wiesz jedyne możliwe kółko na wykresie to samoodniesienie, możemy to zrobić taniej:

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;

Skrzypce SQL.

Zauważ, że wystąpiłyby problemy (przynajmniej do pg v9.4) dla typów danych z modyfikatorem (takim jak varchar(5) ), ponieważ konkatenacja tablic traci modyfikator, ale rCTE nalega na dokładne dopasowanie typów:

  • Zaskakujące wyniki dla typów danych z modyfikatorem typu


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Czy mogę poprosić Postgresql o ignorowanie błędów w transakcji?

  2. Jak Atan2() działa w PostgreSQL

  3. Zwróć zgrupowaną listę z wystąpieniami za pomocą Rails i PostgreSQL

  4. PostgreSQL:Jak przekazać parametry z wiersza poleceń?

  5. Jak zresetować sekwencję w postgresie i wypełnić kolumnę id nowymi danymi?