PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Postgres analogue à CROSS APPLY dans SQL Server

Dans Postgres 9.3 ou plus tard utiliser un LATERAL rejoindre :

SELECT v.col_a, v.col_b, f.*  -- no parentheses here, f is a table alias
FROM   v_citizenversions v
LEFT   JOIN LATERAL f_citizen_rec_modified(v.col1, v.col2) f ON true
WHERE  f.col_c = _col_c;

Pourquoi LEFT JOIN LATERAL ... ON true ?

  • L'enregistrement renvoyé par la fonction a des colonnes concaténées

Pour les anciennes versions , il existe un moyen très simple d'accomplir ce que je pense vous essayez avec une fonction de retour d'ensemble (RETURNS TABLE ou RETURNS SETOF record OR RETURNS record ):

SELECT *, (f_citizen_rec_modified(col1, col2)).*
FROM   v_citizenversions v

La fonction calcule les valeurs une fois pour chaque ligne de la requête externe. Si la fonction renvoie plusieurs lignes, les lignes résultantes sont multipliées en conséquence. Toutes les parenthèses sont syntaxiquement requises pour décomposer un type de ligne. La fonction de table pourrait ressembler à ceci :

CREATE OR REPLACE FUNCTION f_citizen_rec_modified(_col1 int, _col2 text)
  RETURNS TABLE(col_c integer, col_d text) AS
$func$
SELECT s.col_c, s.col_d
FROM   some_tbl s
WHERE  s.col_a = $1
AND    s.col_b = $2
$func$ LANGUAGE sql;

Vous devez envelopper cela dans une sous-requête ou CTE si vous souhaitez appliquer un WHERE clause car les colonnes ne sont pas visibles au même niveau. (Et c'est quand même mieux pour les performances, car vous évitez l'évaluation répétée pour chaque colonne de sortie de la fonction) :

SELECT col_a, col_b, (f_row).*
FROM (
   SELECT col_a, col_b, f_citizen_rec_modified(col1, col2) AS f_row
   FROM   v_citizenversions v
   ) x
WHERE (f_row).col_c = _col_c;

Il existe plusieurs autres façons de faire cela ou quelque chose de similaire. Tout dépend de ce que vous voulez exactement.