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

SQL Znajdź wszystkich bezpośrednich potomków w drzewie

W nowym PostgreSQL 8.4 możesz to zrobić za pomocą CTE :

WITH RECURSIVE q AS
        (
        SELECT  h, 1 AS level, ARRAY[id] AS breadcrumb
        FROM    t_hierarchy h
        WHERE   parent = 0
        UNION ALL
        SELECT  hi, q.level + 1 AS level, breadcrumb || id
        FROM    q
        JOIN    t_hierarchy hi
        ON      hi.parent = (q.h).id
        )
SELECT  REPEAT('  ', level) || (q.h).id,
        (q.h).parent,
        (q.h).value,
        level,
        breadcrumb::VARCHAR AS path
FROM    q
ORDER BY
        breadcrumb

Zobacz ten artykuł na moim blogu, aby uzyskać szczegółowe informacje:

W 8.3 lub wcześniej musisz napisać funkcję:

CREATE TYPE tp_hierarchy AS (node t_hierarchy, level INT);

CREATE OR REPLACE FUNCTION fn_hierarchy_connect_by(INT, INT)
RETURNS SETOF tp_hierarchy
AS
$$
        SELECT  CASE
                WHEN node = 1 THEN
                        (t_hierarchy, $2)::tp_hierarchy
                ELSE
                        fn_hierarchy_connect_by((q.t_hierarchy).id, $2 + 1)
                END
        FROM    (
                SELECT  t_hierarchy, node
                FROM    (
                        SELECT  1 AS node
                        UNION ALL
                        SELECT  2
                        ) nodes,
                        t_hierarchy
                WHERE   parent = $1
                ORDER BY
                        id, node
                ) q;
$$
LANGUAGE 'sql';

i wybierz z tej funkcji:

SELECT  *
FROM    fn_hierarchy_connect_by(4, 1)

Pierwszym parametrem jest główny id , drugi powinien mieć wartość 1 .

Zobacz ten artykuł na moim blogu, aby uzyskać więcej informacji:

Aktualizacja:

Aby wyświetlić tylko dzieci pierwszego poziomu lub sam węzeł, jeśli dzieci nie istnieją, wyślij to zapytanie:

SELECT  *
FROM    t_hierarchy
WHERE   parent = @start
UNION ALL
SELECT  *
FROM    t_hierarchy
WHERE   id = @start
        AND NOT EXISTS
        (
        SELECT  NULL
        FROM    t_hierarchy
        WHERE   parent = @start
        )

Jest to bardziej wydajne niż JOIN , ponieważ drugie zapytanie zajmie najwyżej dwa skany indeksu:pierwsze, aby sprawdzić, czy dziecko istnieje, drugie, aby wybrać wiersz nadrzędny, jeśli nie ma dzieci.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tablica PHP do tablicy postgres

  2. Łączenie PostgreSQL 9.2.1 z Hibernate

  3. PostgreSQL ignoruje myślniki podczas składania zamówienia

  4. Zapytanie przy użyciu dwóch wartości kolumn do utworzenia zakresu

  5. Wstawianie kolumny json Postgresa za pomocą wildfly