PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Rekursive Funktion in Ansicht umwandeln

Einfachere Funktion

Zunächst einmal können Sie vereinfachen Ihre Funktion ziemlich viel. Diese einfachere SQL-Funktion macht dasselbe:

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;

Aufruf:

select * from f_tree(15);
  • Sie könnten plpgsql verwenden, könnte etwas sein vorteilhaft für das Einlösen des Abfrageplans in Versionen vor PostgreSQL 9.2. Aber Sie haben den einzigen theoretischen Vorteil zunichte gemacht, indem Sie dynamisches SQL ohne Notwendigkeit verwendet haben. Das macht überhaupt keinen Sinn. Zu einfachem SQL vereinfachen.

  • Verwenden Sie UNION ALL statt UNION , billiger, da es absichtlich keine Duplikate geben kann.

Nur SQL

Natürlich können Sie dies durch einfaches SQL ersetzen:

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;

Tut das gleiche.

ANSEHEN

Jetzt die VIEW ist eine triviale Angelegenheit:

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;

Das Ergebnis macht für mich nicht viel Sinn, aber die Frage definiert nichts Sinnvolleres..