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

Намиране на обхващаща гора (С RECURSIVE, PostgreSQL 9.5)

Написах отговор на подобен въпрос преди малко:Как да намеря всички свързани подграфи на ненасочена графа . В този въпрос използвах SQL Server. Вижте този отговор за подробно обяснение на междинните CTE. Адаптирах тази заявка към Postgres.

Може да се напише по-ефективно, като се използва функцията за масив на Postgres, вместо да се свързва пътя в текст колона.

WITH RECURSIVECTE_IdentsAS( SELECT old AS Ident FROM identities UNION SELECT new AS Ident FROM identities),CTE_PairsAS( SELECT old AS Ident1, new AS Ident2 FROM identities WHERE old <> new UNION SELECT new AS Ident1, old AS Ident2 FROM identities WHERE old <> new),CTE_RecursiveAS( SELECT CTE_Idents.Ident AS AnchorIdent, Ident1, Ident2, ',' || Ident1 || ',' || Ident2 || ',' AS IdentPath, 1 AS Lvl FROM CTE_Pairs INNER JOIN CTE_Idents ON CTE_Idents.Ident =CTE_Pairs.Ident1 UNION ALL SELECT CTE_Recursive.AnchorIdent, CTE_Pairs.Ident1, CTE_Pairs.Ident2, CTE_Recursive.IdentPath || CTE_Pairs.Ident2 || ',' AS IdentPath, CTE_Recursive.Lvl + 1 AS CTE_Recursive.Lvl_Pal FROM AS Lvl INNER JOIN CTE_Recursive ON CTE_Recursive.Ident2 =CTE_Pairs.Ident1 WHERE CTE_Recursive.IdentPath NOT LIKE ('%,' || CTE_Pairs.Ident2 || ',%')),CTE_Recursi onResultas (Изберете Anchorident, Ident1, Ident2 от CTE_RECURSIVE), CTE_CLEANRESULTAS (Изберете Anchordent, Ident1 като идентификация от CTE_RECURSIONRESULT UNION SELECT ANCHOREDID, IDECTS като идентификация от cte_recursionresult), cte_groupsas (select cte_idents. Ident) ORDER BY COALESCE(CTE_CleanResult.Ident, CTE_Idents.Ident)) AS AllIdents FROM CTE_Idents LEFT JOIN CTE_CleanResult ON CTE_CleanResult.AnchorIdent =CTE_Idents.Ident GROUP BY CTE_Idents.Ident)SELECT AllIdentsFROM CTE_GroupsGROUP BY All Idents; BY AllIdents 

Добавих един ред (7,X,Y) към вашите примерни данни.

SQL Fiddle

Резултат

<предварителен код>| алиденти ||--------------------|| Лидия, Мери, Нанси || Албърт, Боб, Чарлз || X,Y || Зоуи |



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. релацията не е намерена с помощта на Postgres в приложение Eclipse Hibernate

  2. Влияние на производителността на изгледа върху агрегатната функция спрямо ограничаването на набора от резултати

  3. Как правилно да създам речник на тезауруса за моята персонализирана конфигурация за търсене на текст

  4. Как да направя заявка, използвайки полета в новия PostgreSQL JSON тип данни?

  5. Генериране на обект за единична таблица