PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

PostgreSQL meneruskan data dari CTE rekursif ke fungsi

Anda dapat membuat pencarian jalur lebih efisien jika Anda mulai dari bawah. Mulai dari anak-anak. Jika Anda mulai dari orang tua, itu berarti melintasi semua anak; sedangkan jika Anda mencari dari anak, ia hanya memiliki satu orang tua, maka tidak akan membuang waktu untuk menemukan jalur antara sumber dan target.

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

Keluaran:

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

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

Mirip dengan ini:Cara mendapatkan orang tua yang diberikan anak di SQL SERVER 2005

Ini dioptimalkan, potong rekursi ke induk jika sudah menemukan yang spesifik (sumber).

Sumber =2

Target =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

Keluaran:

SOURCE   TARGET  PATH
2        4       2.4
4        9       2.4.9

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dapatkan nama pemilik DB di PostgreSql

  2. PostgreSQL:Pelanggaran unik:7 ERROR:nilai kunci duplikat melanggar batasan unik users_pkey

  3. dapatkan tabel GABUNG sebagai array hasil dengan PostgreSQL/NodeJS

  4. Bidang pembaruan SQL dari satu tabel dari bidang yang lain

  5. Cara mengambil cadangan fungsi hanya di Postgres