आप कई जगहों पर सरल बना सकते हैं (acct_id
. मानते हुए) और parent_id
हैं NOT NULL
):
WITH RECURSIVE search_graph AS (
SELECT parent_id, ARRAY[acct_id] AS path
FROM account
UNION ALL
SELECT g.parent_id, sg.path || g.acct_id
FROM search_graph sg
JOIN account g ON g.acct_id = sg.parent_id
WHERE g.acct_id <> ALL(sg.path)
)
SELECT path[1] AS child
, path[array_upper(path,1)] AS parent
, path
FROM search_graph
ORDER BY path;
- कॉलम
acct_id
,depth
,cycle
आपकी क्वेरी में केवल शोर हैं। WHERE
कंडीशन को रिकर्सन से एक कदम पहले, पहले . से बाहर निकलना होगा परिणाम में शीर्ष नोड से डुप्लिकेट प्रविष्टि है। यह आपके मूल में "एक-एक करके" था।
बाकी स्वरूपण है।
अगर आप जानते हैं आपके ग्राफ़ में एकमात्र संभावित वृत्त एक आत्म-संदर्भ है, हमारे पास वह सस्ता हो सकता है:
WITH RECURSIVE search_graph AS (
SELECT parent_id, ARRAY[acct_id] AS path, acct_id <> parent_id AS keep_going
FROM account
UNION ALL
SELECT g.parent_id, sg.path || g.acct_id, g.acct_id <> g.parent_id
FROM search_graph sg
JOIN account g ON g.acct_id = sg.parent_id
WHERE sg.keep_going
)
SELECT path[1] AS child
, path[array_upper(path,1)] AS parent
, path
FROM search_graph
ORDER BY path;
एसक्यूएल फिडल.
ध्यान दें कि संशोधक वाले डेटा प्रकारों के लिए (कम से कम pg v9.4 तक) समस्याएं होंगी (जैसे varchar(5)
) क्योंकि सरणी संयोजन संशोधक को खो देता है लेकिन आरसीटीई सटीक रूप से मेल खाने वाले प्रकारों पर जोर देता है:
- प्रकार संशोधक के साथ डेटा प्रकारों के लिए आश्चर्यजनक परिणाम