sql >> Database teknologi >  >> RDS >> PostgreSQL

Postgresql ltree-forespørgsel for at finde forældre med de fleste børn; ekskl. rod

Løsning

Sådan finder du noden med flest børn:

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

... og ekskluder rodnoder:

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

Forudsat at rodnoder har et tomt ltree ('' ) som vej. Måske NULL . Brug derefter path IS NULL ...

Vinderen i dit eksempel er faktisk 2001 , med 5 børn.

-> SQLfiddle

Hvordan?

  • Brug funktionen subpath(...) leveret af ekstramodulet ltree .

  • Hent den sidste node i stien med en negativ offset , som er den direkte overordnede for elementet.

  • Tæl hvor ofte den forælder optræder, ekskluder rodnoder og tag den resterende med det højeste antal.

  • Brug ltree2text() for at udtrække værdien fra ltree .

  • Hvis flere noder har lige mange børn, vælges en vilkårlig i eksemplet.

Testcase

Dette er det arbejde, jeg skulle udføre for at komme til en nyttig testsag (efter at have trimmet noget støj):

Se SQLfiddle .

Med andre ord:husk venligst at give en nyttig testcase næste gang.

Yderligere kolonner

Svar til kommentar.
Udvid først testcasen:

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

Tag et kig:

SELECT * FROM tbl;

Bare JOIN resultat til det overordnede i basistabellen:

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. Bredt varchar-felt årsager Anmodet konvertering understøttes ikke fejl ved brug af openquery med MySQL-linket server

  2. Forskel mellem datoer i to på hinanden følgende rækker

  3. MySQL-replikering og GTID-baseret failover - et dybt dyk ned i fejlagtige transaktioner

  4. hvordan ændres postgresql lytteport i Windows?