PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Postgresql zapytanie ltree, aby znaleźć rodzica z większością dzieci; z wyłączeniem korzenia

Rozwiązanie

Aby znaleźć węzeł z największą liczbą dzieci:

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

... i wyklucz węzły główne:

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

Zakładając, że węzły główne mają puste ltree ('' ) jako ścieżka. Może być NULL . Następnie użyj path IS NULL ...

Zwycięzcą w twoim przykładzie jest w rzeczywistości 2001 , z pięciorgiem dzieci.

-> SQLfiddle

Jak?

  • Użyj funkcji subpath(...) dostarczony przez dodatkowy moduł ltree .

  • Pobierz ostatni węzeł na ścieżce z ujemnym przesunięciem , który jest bezpośrednim rodzicem elementu.

  • Policz, jak często pojawia się ten rodzic, wyklucz węzły główne i weź pozostały z największą liczbą.

  • Użyj ltree2text() aby wyodrębnić wartość z ltree .

  • Jeśli wiele węzłów ma jednakowo najwięcej dzieci, w przykładzie wybierany jest dowolny.

Przypadek testowy

To jest praca, którą musiałem wykonać, aby dostać się do użytecznego przypadku testowego (po przycięciu trochę szumu):

Zobacz SQLfiddle .

Innymi słowy:pamiętaj, aby następnym razem dostarczyć przydatny przypadek testowy.

Dodatkowe kolumny

Odpowiedz na komentarz.
Najpierw rozwiń przypadek testowy:

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

Zobacz:

SELECT * FROM tbl;

Po prostu JOIN wynik do rodzica w tabeli bazowej:

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. dodatkowe dane po ostatniej oczekiwanej kolumnie podczas próby importowania pliku csv do postgresql

  2. Jakiego NpgsqlDbType należy użyć do usunięcia błędu Can't write CLR type

  3. PostgreSQL:Jak SUM atrybuty, w tym pole JSONB, i zachować kształt tabeli?

  4. Django Postgresql usuwa domyślne ustawienia kolumn podczas migracji

  5. pgFincore 1.2, rozszerzenie PostgreSQL