sql >> Databáze >  >> RDS >> PostgreSQL

Dotaz Postgresql ltree k nalezení rodiče s většinou dětí; kromě kořene

Řešení

Chcete-li najít uzel s největším počtem dětí:

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

... a vyloučit kořenové uzly:

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

Za předpokladu, že kořenové uzly mají prázdný ltree ('' ) jako cestu. Může být NULL . Poté použijte path IS NULL ...

Vítěz ve vašem příkladu je ve skutečnosti 2001 , s 5 dětmi.

-> SQLfiddle

Jak?

  • Použijte funkci subpath(...) poskytuje doplňkový modul ltree .

  • Získejte poslední uzel v cestě s záporným posunem , který je přímým rodičem prvku.

  • Spočítejte, jak často se tento rodič objevuje, vylučte kořenové uzly a vezměte zbývající s nejvyšším počtem.

  • Použijte ltree2text() extrahovat hodnotu z ltree .

  • Pokud má více uzlů stejně nejvíce potomků, vybere se v příkladu libovolný.

Testovací případ

Toto je práce, kterou jsem musel udělat, abych se dostal k užitečnému testovacímu případu (po oříznutí nějakého šumu):

Viz SQLfiddle .

Jinými slovy:nezapomeňte prosím příště poskytnout užitečný testovací případ.

Další sloupce

Odpovězte na komentář.
Nejprve rozbalte testovací případ:

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

Podívejte se:

SELECT * FROM tbl;

Jednoduše JOIN výsledek k nadřazenému v základní tabulce:

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. Načíst data z databáze + ajax + php

  2. Jak vypočítat rozdíl v hodinách (desetinně) mezi dvěma daty na serveru SQL?

  3. MySQL:Vnitřní spojení vs kde

  4. Další nejbližší datum a čas v MySQL