Lösung
So finden Sie den Knoten mit den meisten Kindern:
SELECT subpath(path, -1, 1), count(*) AS children
FROM tbl
WHERE path <> ''
GROUP BY 1
ORDER BY 2 DESC
LIMIT 1;
... und Wurzelknoten ausschließen:
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
Angenommen, die Wurzelknoten haben einen leeren ltree
(''
) als Pfad. Könnte NULL
sein . Verwenden Sie dann path IS NULL
...
Der Gewinner in Ihrem Beispiel ist eigentlich 2001
, mit 5 Kindern.
Wie?
-
Verwenden Sie die Funktion
subpath(...)
bereitgestellt vom dem zusätzlichen Modulltree
. -
Holen Sie sich den letzten Knoten im Pfad mit einem negativen Offset , das das direkte übergeordnete Element des Elements ist.
-
Zählen Sie, wie oft dieser Elternknoten vorkommt, schließen Sie Wurzelknoten aus und nehmen Sie den verbleibenden Knoten mit der höchsten Anzahl.
-
Verwenden Sie
ltree2text()
um den Wert ausltree
zu extrahieren . -
Wenn mehrere Knoten gleich viele Kinder haben, wird im Beispiel ein beliebiges gewählt.
Testfall
Dies ist die Arbeit, die ich tun musste, um zu einem nützlichen Testfall zu gelangen (nachdem ich etwas Rauschen getrimmt habe):
Siehe SQLfiddle .
Mit anderen Worten:Bitte denken Sie beim nächsten Mal daran, einen nützlichen Testfall bereitzustellen.
Zusätzliche Spalten
Antwort auf Kommentar.
Erweitern Sie zuerst den Testfall:
ALTER TABLE tbl ADD COLUMN postal_code text
, ADD COLUMN whatever serial;
UPDATE tbl SET postal_code = (1230 + whatever)::text;
Schau mal:
SELECT * FROM tbl;
Einfach JOIN
Ergebnis zum Elternteil in der Basistabelle:
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;