sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL skickar data från rekursiv CTE till funktion

Du kan effektivisera sökningen av vägen om du börjar längst ner. Börja med barnen. Om man börjar hos föräldern innebär det att man går igenom alla barn; medan om du sökte från barnet, har det bara en förälder, och kommer därför inte att slösa tid på att hitta vägen mellan källa och mål.

with recursive find_parent(source, target, recentness) as
(
    select source, target, 0 
    from tbl
    where target = 9

    union all

    select i.source, i.target, fp.recentness + 1
    from tbl i
    join find_parent fp on i.target = fp.source
),
construct_path(source, target, recentness, path) as
(
  select source, target, recentness, source || '.' || target
  from find_parent 
  where recentness = (select max(recentness) from find_parent)

  union

  select dd.source, dd.target, dd.recentness, cp.path || '.' || dd.target
  from find_parent dd
  join construct_path cp on dd.recentness = cp.recentness - 1  
)
select source, target, path 
from construct_path
order by recentness desc

Utdata:

SOURCE   TARGET   PATH
1        2        1.2
2        4        1.2.4
4        9        1.2.4.9

Livetest:http://www.sqlfiddle.com/#!1/13e6b/1

Liknande detta:Hur man får föräldern ges ett barn i SQL SERVER 2005

Detta är optimerat, skär rekursion till förälder om den redan hittar den specifika (källan).

Källa =2

Mål =9

with recursive find_parent(source, target, recentness) as
(
    select source, target, 0 
    from tbl
    where target = 9

    union all

    select i.source, i.target, fp.recentness + 1
    from tbl i
    join find_parent fp on i.target = fp.source 
         -- despite the name, this target is another one's source
         and i.target <> 2
)
,construct_path(source, target, recentness, path) as
(
    select source, target, recentness, source || '.' || target
    from find_parent 
    where recentness = (select max(recentness) from find_parent)

    union

    select dd.source, dd.target, dd.recentness, cp.path || '.' || dd.target
    from find_parent dd
    join construct_path cp on dd.recentness = cp.recentness - 1  

)
select source, target, path
from construct_path
order by recentness desc

Utdata:

SOURCE   TARGET  PATH
2        4       2.4
4        9       2.4.9

Livetest:http://www.sqlfiddle.com/#!1/13e6b/16



  1. Kör PostgreSQL-frågor från kommandoraden

  2. Hur man hittar alla begränsningsöverträdelser i en SQL Server-databas

  3. Python SQL – Hur man använder SQLite-, MySQL- och PostgreSQL-databaserna med Python

  4. Databasdesign för användarinställningar