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

Deteksi item duplikat dalam CTE rekursif

Kata dep dalam kueri kedua (setelah union ) bersifat ambigu. Sebenarnya itu ditafsirkan sebagai kolom rdeps , bukan sebagai alias dari objectdependencies.

with recursive rdeps as (
  select dep
  from objectdependencies dep
  where dep.dependson = 4 -- starting point
  union all
  select dep -- this means r.dep
  from objectdependencies dep
  join rdeps r
    on (r.dep).id = dep.dependson
) select (dep).id from rdeps;

Inilah sebabnya mengapa kueri membuat loop tanpa akhir. Anda dapat memperbaikinya dengan mengubah alias:

with recursive rdeps as (
  select dep
  from objectdependencies dep
  where dep.dependson = 4 -- starting point
  union all
  select objectdep
  from objectdependencies objectdep
  join rdeps r
    on (r.dep).id = objectdep.dependson
) select (dep).id from rdeps;

 id 
----
  1
  2
  3
  1
  2
  1
(6 rows)    

Atau lebih baik, hanya dengan menggunakan kolom, seperti yang diinginkan Tuhan:

with recursive rdeps as (
    select id, dependson
    from objectdependencies
    where dependson = 4
union all
    select d.id, d.dependson
    from objectdependencies d
    join rdeps r
    on r.id = d.dependson
) 
select *
from rdeps;

Kueri pertama dalam pertanyaan adalah semua yang dapat Anda lakukan dalam sql biasa karena tidak ada komunikasi antara berbagai cabang (paralel) yang dihasilkan oleh kueri rekursif. Dalam pendekatan fungsional Anda dapat menggunakan tabel sementara sebagai toko umum untuk semua cabang. Fungsinya mungkin terlihat seperti ini:

create or replace function rec_function(int)
returns void language plpgsql as $$
declare
    i int;
begin
    for i in
        select id
        from objectdependencies
        where dependson = $1
    loop
        if not exists(
            select from temp_table 
            where id = i)
        then
            insert into temp_table values(i);
            perform rec_function(i);
        end if;
    end loop;
end $$;

Penggunaan:

create temp table temp_table(id int);

select rec_function(4);

select *
from temp_table;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara meminta nilai nol dalam jenis bidang json postgresql?

  2. Bagaimana menghubungkan Struts 2 dengan Hibernate dan PostgreSQL

  3. Dapatkan Nama Hari dari Tanggal di PostgreSQL

  4. PostgreSQL Penskalaan Vertikal

  5. Cara Menggunakan pgBackRest untuk Mencadangkan PostgreSQL dan TimescaleDB