PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Рекурсивна заявка, използвана за преходно затваряне

Можете да опростите на няколко места (приемайки acct_id и 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;
  • Колоните acct_id , depth , cycle са просто шум във вашата заявка.
  • WHERE условието трябва да излезе от рекурсията една стъпка по-рано, преди дублираният запис от горния възел е в резултата. Това беше „изключено по едно“ във вашия оригинал.

Останалото е форматиране.

Ако знаете единственият възможен кръг във вашата графика е самореференция, можем да имаме това по-евтино:

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.

Имайте предвид, че ще има проблеми (поне до pg v9.4) за типове данни с модификатор (като varchar(5) ), защото конкатенацията на масив губи модификатора, но rCTE настоява типове да съвпадат точно:

  • Изненадващи резултати за типове данни с модификатор на тип


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Свържете параметъра на масива към собствената заявка

  2. Създаване на потребител на PostgreSQL и добавянето им към база данни

  3. ClusterControl - Разширено управление на архивиране - PostgreSQL

  4. Най-добрият начин да инсталирате hstore на множество схеми в база данни на Postgres?

  5. PostgreSQL - как да изобразя дата в различна часова зона?