sql >> Databáze >  >> RDS >> PostgreSQL

Detekce duplicitních položek v rekurzivním CTE

Slovo dep ve druhém dotazu (po union ) je nejednoznačný. Ve skutečnosti je interpretován jako sloupec rdeps , nikoli 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;

To je důvod, proč dotaz vytváří nekonečnou smyčku. Můžete to opravit změnou aliasu:

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)    

Nebo lépe, jen pomocí sloupců, jak to zamýšlel dobrý Pán:

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;

První dotaz v otázce je vše, co můžete udělat v prostém SQL, protože neexistuje žádná komunikace mezi různými (paralelními) větvemi generovanými rekurzivním dotazem. Ve funkčním přístupu můžete použít dočasný stůl jako úložiště společný pro všechny pobočky. Funkce může vypadat takto:

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

Použití:

create temp table temp_table(id int);

select rec_function(4);

select *
from temp_table;


  1. Průvodce návrhem databáze pro kvíz v MySQL

  2. Najděte velikost bajtů řádku v PostgreSQL

  3. Formát data MySQL DD/MM/RRRR vybrat dotaz?

  4. Jak vytvořit tabulku s omezením cizího klíče v SQL Server - SQL Server / TSQL výukový program, část 66