PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

SQL Temukan semua keturunan langsung di pohon

Di PostgreSQL 8.4 baru Anda dapat melakukannya dengan 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

Lihat artikel ini di blog saya untuk detailnya:

Di 8.3 atau sebelumnya, Anda harus menulis fungsi:

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';

dan pilih dari fungsi ini:

SELECT  *
FROM    fn_hierarchy_connect_by(4, 1)

Parameter pertama adalah root id , yang kedua harus 1 .

Lihat artikel ini di blog saya untuk detail lebih lanjut:

Pembaruan:

Untuk menampilkan hanya anak-anak tingkat pertama, atau simpul itu sendiri jika anak-anak tidak ada, buat kueri ini:

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
        )

Ini lebih efisien daripada JOIN , karena kueri kedua akan mengambil paling banyak dua pemindaian indeks:yang pertama untuk memastikan apakah ada anak, yang kedua untuk memilih baris induk jika tidak ada anak.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. django.db.utils.OperationalError:tidak dapat terhubung ke server:Tidak ada file atau direktori seperti itu

  2. Bagaimana cara meningkatkan otomatis di PostgreSQL?

  3. Kondisi SQL pada fungsi Window

  4. Atomikos:data tidak disimpan saat menggunakan PostgreSQL

  5. Bisakah saya mengembalikan transaksi yang sudah saya lakukan? (Data hilang)