Solução
Para encontrar o nó com mais filhos:
SELECT subpath(path, -1, 1), count(*) AS children
FROM tbl
WHERE path <> ''
GROUP BY 1
ORDER BY 2 DESC
LIMIT 1;
... e exclua os nós raiz:
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
Supondo que os nós raiz tenham um
ltree
vazio (''
) como caminho. Pode ser NULL
. Em seguida, use path IS NULL
... O vencedor no seu exemplo é, na verdade,
2001
, com 5 filhos. -> SQLfiddle
Como?
-
Use a funçãosubpath(...)
fornecido pelo o módulo adicionalltree
.
-
Obtenha o último nó no caminho com um deslocamento negativo , que é o pai direto do elemento.
-
Conte com que frequência esse pai aparece, exclua nós raiz e pegue o restante com a contagem mais alta.
-
Useltree2text()
para extrair o valor deltree
.
-
Se vários nós tiverem o mesmo número de filhos, um arbitrário será escolhido no exemplo.
Caso de teste
Este é o trabalho que tive que fazer para chegar a um caso de teste útil (depois de cortar algum ruído):
Consulte SQLfiddle .
Em outras palavras:lembre-se de fornecer um caso de teste útil da próxima vez.
Colunas adicionais
Responda ao comentário.
Primeiro, expanda o caso de teste:
ALTER TABLE tbl ADD COLUMN postal_code text
, ADD COLUMN whatever serial;
UPDATE tbl SET postal_code = (1230 + whatever)::text;
Dar uma olhada:
SELECT * FROM tbl;
Simplesmente
JOIN
resultado para o pai na tabela base: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;