PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

làm cách nào tôi có thể lấy tất cả id bắt đầu từ một id đã cho một cách đệ quy trong một bảng postgresql tham chiếu đến chính nó?

Sử dụng biểu thức bảng chung đệ quy . Luôn bắt đầu từ gốc, sử dụng một mảng id để lấy đường dẫn cho một id nhất định trong WHERE mệnh đề.

Đối với 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)

Đối với 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)    

Truy vấn hai chiều

Câu hỏi thực sự thú vị. Truy vấn trên hoạt động tốt nhưng không hiệu quả vì nó phân tích cú pháp tất cả các nút cây ngay cả khi chúng tôi yêu cầu một lá. Giải pháp mạnh mẽ hơn là truy vấn đệ quy hai chiều. Truy vấn bên trong đi từ một nút nhất định lên trên cùng, trong khi truy vấn bên ngoài đi từ nút xuống dưới cùng.

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. Rails 4 session. Thỉnh thoảng là con số không

  2. Làm cách nào để chỉ tham gia một hàng trong bảng đã tham gia với postgres?

  3. Làm thế nào để triển khai mối quan hệ nhiều-nhiều trong PostgreSQL?

  4. Làm cách nào để tôi có được các hàng ĐÃ CHÈN và CẬP NHẬT cho hoạt động UPSERT trong postgres

  5. Postgres - Làm cách nào để chuyển đổi hàng có phạm vi int thành các hàng trung gian từ các giá trị riêng lẻ từ phạm vi đó?