sql >> Databasteknik >  >> RDS >> PostgreSQL

Postgresql ltree-fråga för att hitta förälder med de flesta barn; exklusive rot

Lösning

Så här hittar du noden med flest barn:

SELECT subpath(path, -1, 1), count(*) AS children
FROM   tbl
WHERE  path <> ''
GROUP  BY 1
ORDER  BY 2 DESC
LIMIT  1;

... och exkludera rotnoder:

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

Förutsatt att rotnoder har ett tomt ltree ('' ) som väg. Kan vara NULL . Använd sedan path IS NULL ...

Vinnaren i ditt exempel är faktiskt 2001 , med 5 barn.

-> SQLfiddle

Hur?

  • Använd funktionen subpath(...) tillhandahålls av tilläggsmodulen ltree .

  • Hämta den sista noden i sökvägen med en negativ offset , som är den direkta föräldern till elementet.

  • Räkna hur ofta den föräldern visas, exkludera rotnoder och ta den återstående med det högsta antalet.

  • Använd ltree2text() för att extrahera värdet från ltree .

  • Om flera noder har lika många barn väljs en godtycklig i exemplet.

Testfall

Det här är arbetet jag var tvungen att göra för att komma till ett användbart testfall (efter att ha trimmat lite brus):

Se SQLfiddle .

Med andra ord:kom ihåg att ge ett användbart testfall nästa gång.

Ytterligare kolumner

Svar på kommentar.
Utöka först testfallet:

ALTER TABLE tbl ADD COLUMN postal_code text
              , ADD COLUMN whatever serial;
UPDATE tbl SET postal_code = (1230 + whatever)::text;

Ta en titt:

SELECT * FROM tbl;

JOIN resultat till det överordnade i bastabellen:

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;



  1. FEL:mer än en rad returneras av en underfråga som används som uttryck

  2. Uppdatera kolumn med slumpmässiga unika värden från en annan tabell

  3. PostgreSQL på väg upp:2018 Postgres fynd och 2019 trender

  4. Välj användare som endast tillhör vissa avdelningar