PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Converter função recursiva para visualização

Função mais simples


Em primeiro lugar, você pode simplificar bastante sua função. Esta função SQL mais simples faz o mesmo:
CREATE OR REPLACE FUNCTION f_tree(_rev int)
 RETURNS TABLE(id int, parent_id int, depth int) AS
$func$
   WITH RECURSIVE tree_list AS (
      SELECT t.id, t.parent_id, 1 -- AS depth
      FROM   tree t
      WHERE  t.id = $1

      UNION ALL  -- no point using UNION
      SELECT t.id, t.parent_id, r.depth + 1
      FROM   tree_list r
      JOIN   tree t ON t.id = r.parent_id
      )
   SELECT t.id, t.parent_id, t.depth
   FROM   tree_list t
   ORDER  BY t.id;
$func$ LANGUAGE sql;

Ligar:
select * from f_tree(15);

  • Você poderia use plpgsql, pode ser ligeiramente benéfico para descontar o plano de consulta em versões anteriores ao PostgreSQL 9.2. Mas você anulou o único benefício teórico usando SQL dinâmico sem necessidade. Isso não faz o menor sentido. Simplifique para SQL simples.

  • Use UNION ALL em vez de UNION , mais barato, pois não pode haver enganos por design.

Apenas SQL


Obviamente, você pode substituir isso por SQL simples:
WITH RECURSIVE tree_list AS (
   SELECT t.id, t.parent_id, 1 AS depth
   FROM   tree t
   WHERE  t.id = 15  -- enter parameter here

   UNION ALL
   SELECT t.id, t.parent_id, r.depth + 1
   FROM   tree_list r
   JOIN   tree t ON t.id = r.parent_id
   )
SELECT t.id, t.parent_id, t.depth
FROM   tree_list t
ORDER  BY t.id;

Faz o mesmo.

VER


Agora, o VIEW é uma questão trivial:
CREATE OR REPLACE VIEW v_tree15 AS
WITH RECURSIVE tree_list AS (
   SELECT t.id, t.parent_id, 1 AS depth
   FROM   tree t
   WHERE  t.id <= 15   -- only detail to change

   UNION ALL
   SELECT t.id, t.parent_id, r.depth + 1
   FROM   tree_list r
   JOIN   tree t ON t.id = r.parent_id
   )
SELECT t.id, t.parent_id, t.depth
FROM   tree_list t
ORDER  BY t.id;

O resultado não faz muito sentido para mim, mas a questão não define nada mais sensato..