PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

मैं किसी दिए गए आईडी से एक पोस्टग्रेस्क्ल तालिका में पुनरावर्ती रूप से शुरू होने वाली सभी आईडी कैसे प्राप्त कर सकता हूं जो स्वयं को संदर्भित करता है?

रिकर्सिव कॉमन टेबल एक्सप्रेशन का इस्तेमाल करें . हमेशा रूट से शुरू करते हुए, किसी दिए गए id . के लिए पथ प्राप्त करने के लिए id की एक सरणी का उपयोग करें WHERE . में खंड।

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)

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)    

द्विदिशात्मक क्वेरी

सवाल वाकई दिलचस्प है। उपरोक्त क्वेरी अच्छी तरह से काम करती है लेकिन अक्षम है क्योंकि यह सभी ट्री नोड्स को तब भी पार्स करती है जब हम एक पत्ता मांग रहे होते हैं। अधिक शक्तिशाली समाधान एक द्विदिश पुनरावर्ती क्वेरी है। आंतरिक क्वेरी किसी दिए गए नोड से ऊपर तक जाती है, जबकि बाहरी एक नोड से नीचे तक जाती है।

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. postgreSQL - बनाम कोई भी

  2. अनुकूलित करें अनाथ अभिलेखों को हटाने को पोस्टग्रेज करें

  3. यह ~~ किसी भी () के साथ अलग क्यों काम करता है?

  4. Postgresql में कैरिज रिटर्न और नई लाइनें कैसे निकालें?

  5. Postgresql में चल रही क्वेरी के लिए निष्पादन योजना कैसे प्राप्त करें?