नए में PostgreSQL 8.4
आप इसे CTE
. के साथ कर सकते हैं :
WITH RECURSIVE q AS
(
SELECT h, 1 AS level, ARRAY[id] AS breadcrumb
FROM t_hierarchy h
WHERE parent = 0
UNION ALL
SELECT hi, q.level + 1 AS level, breadcrumb || id
FROM q
JOIN t_hierarchy hi
ON hi.parent = (q.h).id
)
SELECT REPEAT(' ', level) || (q.h).id,
(q.h).parent,
(q.h).value,
level,
breadcrumb::VARCHAR AS path
FROM q
ORDER BY
breadcrumb
विवरण के लिए मेरे ब्लॉग में यह लेख देखें:
8.3
. में या इससे पहले, आपको एक फ़ंक्शन लिखना होगा:
CREATE TYPE tp_hierarchy AS (node t_hierarchy, level INT);
CREATE OR REPLACE FUNCTION fn_hierarchy_connect_by(INT, INT)
RETURNS SETOF tp_hierarchy
AS
$$
SELECT CASE
WHEN node = 1 THEN
(t_hierarchy, $2)::tp_hierarchy
ELSE
fn_hierarchy_connect_by((q.t_hierarchy).id, $2 + 1)
END
FROM (
SELECT t_hierarchy, node
FROM (
SELECT 1 AS node
UNION ALL
SELECT 2
) nodes,
t_hierarchy
WHERE parent = $1
ORDER BY
id, node
) q;
$$
LANGUAGE 'sql';
और इस फ़ंक्शन से चुनें:
SELECT *
FROM fn_hierarchy_connect_by(4, 1)
पहला पैरामीटर रूट है id
, दूसरा 1
. होना चाहिए ।
अधिक विवरण के लिए मेरे ब्लॉग में यह लेख देखें:
अपडेट करें:
केवल प्रथम स्तर के बच्चों को दिखाने के लिए, या स्वयं नोड यदि बच्चे मौजूद नहीं हैं, तो यह प्रश्न जारी करें:
SELECT *
FROM t_hierarchy
WHERE parent = @start
UNION ALL
SELECT *
FROM t_hierarchy
WHERE id = @start
AND NOT EXISTS
(
SELECT NULL
FROM t_hierarchy
WHERE parent = @start
)
यह JOIN
. की तुलना में अधिक कुशल है , चूंकि दूसरी क्वेरी में अधिकतम दो इंडेक्स स्कैन होंगे:पहला यह सुनिश्चित करने के लिए कि कोई बच्चा मौजूद है या नहीं, दूसरा कोई बच्चा मौजूद नहीं होने पर पैरेंट पंक्ति का चयन करने के लिए।