समाधान
सबसे अधिक बच्चों वाले नोड को खोजने के लिए:
SELECT subpath(path, -1, 1), count(*) AS children
FROM tbl
WHERE path <> ''
GROUP BY 1
ORDER BY 2 DESC
LIMIT 1;
... और रूट नोड बहिष्कृत करें:
SELECT *
FROM (
SELECT ltree2text(subpath(path, -1, 1))::int AS tbl_id, count(*) AS children
FROM tbl
WHERE path <> ''
GROUP BY 1
) ct
LEFT JOIN (
SELECT tbl_id
FROM tbl
WHERE path = ''
) x USING (tbl_id)
WHERE x.tbl_id IS NULL
ORDER BY children DESC
LIMIT 1
यह मानते हुए कि रूट नोड्स में एक खाली ltree
है (''
) पथ के रूप में। हो सकता है NULL
. फिर path IS NULL
. का उपयोग करें ...
आपके उदाहरण में विजेता वास्तव में 2001
है , 5 बच्चों के साथ।
कैसे?
-
फ़ंक्शन का उपयोग करें
subpath(...)
अतिरिक्त मॉड्यूलltree
द्वारा प्रदान किया गया . -
अंतिम नोड प्राप्त करें पथ में नकारात्मक ऑफ़सेट . के साथ , जो तत्व का प्रत्यक्ष जनक है।
-
गणना करें कि वह माता-पिता कितनी बार दिखाई देते हैं, रूट नोड्स को बाहर करें और शेष को उच्चतम गणना के साथ लें।
-
ltree2text()
का इस्तेमाल करेंltree
. से मान निकालने के लिए । -
यदि एकाधिक नोड्स में समान रूप से सबसे अधिक बच्चे हैं, तो उदाहरण में एक मनमाना चुना जाता है।
टेस्ट केस
यह वह काम है जो मुझे एक उपयोगी परीक्षण मामले में लाने के लिए करना था (कुछ शोर को कम करने के बाद):
देखें SQLfiddle ।
दूसरे शब्दों में:कृपया अगली बार एक उपयोगी परीक्षण केस प्रदान करना याद रखें।
अतिरिक्त कॉलम
टिप्पणी का उत्तर दें।
सबसे पहले, परीक्षण मामले का विस्तार करें:
ALTER TABLE tbl ADD COLUMN postal_code text
, ADD COLUMN whatever serial;
UPDATE tbl SET postal_code = (1230 + whatever)::text;
एक नज़र डालें:
SELECT * FROM tbl;
बस JOIN
मूल तालिका में माता-पिता को परिणाम:
SELECT ct.*, t.postal_code
FROM (
SELECT ltree2text(subpath(path, -1, 1))::int AS tbl_id, count(*) AS children
FROM tbl
WHERE path <> ''
GROUP BY 1
) ct
LEFT JOIN (
SELECT tbl_id
FROM tbl
WHERE path = ''
) x USING (tbl_id)
JOIN tbl t USING (tbl_id)
WHERE x.tbl_id IS NULL
ORDER BY children DESC
LIMIT 1;