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

bagaimana saya bisa mendapatkan semua id mulai dari id yang diberikan secara rekursif dalam tabel postgresql yang mereferensikan dirinya sendiri?

Gunakan ekspresi tabel umum rekursif . Selalu mulai dari root, gunakan larik id untuk mendapatkan jalur untuk id di WHERE klausa.

Untuk id = 1 :

with recursive cte(id, parent, name, ids) as (
    select id, parent, name, array[id]
    from my_table
    where parent is null
union all
    select t.id, t.parent, concat(c.name, t.name, '/'), ids || t.id
    from cte c
    join my_table t on c.id = t.parent
)
select id, name 
from cte
where 1 = any(ids) and id <> 1

 id |         name          
----+-----------------------
  2 | /home/
  5 | /usr/
  6 | /usr/local/
  3 | /home/user/
  4 | /home/user/bin/
(5 rows)

Untuk id = 2 :

with recursive cte(id, parent, name, ids) as (
    select id, parent, name, array[id]
    from my_table
    where parent is null
union all
    select t.id, t.parent, concat(c.name, t.name, '/'), ids || t.id
    from cte c
    join my_table t on c.id = t.parent
)
select id, name 
from cte
where 2 = any(ids) and id <> 2

 id |         name          
----+-----------------------
  3 | /home/user/
  4 | /home/user/bin/
(2 rows)    

Kueri dua arah

Pertanyaannya sungguh menarik. Kueri di atas berfungsi dengan baik tetapi tidak efisien karena mem-parsing semua simpul pohon bahkan ketika kita meminta daun. Solusi yang lebih kuat adalah kueri rekursif dua arah. Kueri bagian dalam berjalan dari simpul yang diberikan ke atas, sedangkan kueri luar berjalan dari simpul ke bawah.

with recursive outer_query(id, parent, name) as (
    with recursive inner_query(qid, id, parent, name) as (
        select id, id, parent, name
        from my_table
        where id = 2        -- parameter
    union all
        select qid, t.id, t.parent, concat(t.name, '/', q.name)
        from inner_query q
        join my_table t on q.parent = t.id
    )
    select qid, null::int, right(name, -1)
    from inner_query
    where parent is null
union all
    select t.id, t.parent, concat(q.name, '/', t.name)
    from outer_query q
    join my_table t on q.id = t.parent
)
select id, name
from outer_query
where id <> 2;          -- parameter



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Log Stacktrace dari Python Interpreter saat ini melalui pemicu PostgreSQL

  2. Kueri PostgreSQL untuk daftar nilai yang diizinkan dalam batasan?

  3. Apakah ada cara untuk menggunakan tipe data postgresql 9.3 sehingga hanya dapat memengaruhi satu sisi?

  4. Transfer data antar database dengan PostgreSQL

  5. Perlengkapan Django memuat sangat lambat