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

Wykryj zduplikowane elementy w rekurencyjnym CTE

Słowo dep w drugim zapytaniu (po union ) jest dwuznaczny. W rzeczywistości jest interpretowany jako kolumna rdeps , a nie jako alias 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;

Dlatego zapytanie tworzy niekończącą się pętlę. Możesz to poprawić, zmieniając 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)    

Albo lepiej, po prostu używając kolumn, tak jak zamierzył to dobry Pan:

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;

Pierwsze zapytanie w pytaniu to wszystko, co możesz zrobić w zwykłym sql, ponieważ nie ma komunikacji między różnymi (równoległymi) gałęziami generowanymi przez zapytanie rekurencyjne. W podejściu funkcjonalnym można wykorzystać tabelę tymczasową jako magazyn wspólny dla wszystkich oddziałów. Funkcja może wyglądać tak:

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

Użycie:

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. Model Django jeden klucz obcy do wielu tabel

  2. W Railsach nie można utworzyć bazy danych dla {adapter=>postgresql,

  3. Domyślna lokalizacja bazy danych PostgreSQL w systemie Linux

  4. Niekompatybilność Openshift i net-ssh? (2.9.3-beta1 vs 2.9.2)

  5. Jak obracać logi PgBouncera w systemie Linux/Windows?