Compte tenu de cette configuration dans Postgres actuel 9.4 ( à partir de cette question connexe ):
CREATE TABLE foo (ts, foo) AS
VALUES (1, 'A') -- int, text
, (7, 'B');
CREATE TABLE bar (ts, bar) AS
VALUES (3, 'C')
, (5, 'D')
, (9, 'E');
Il y a aussi un SQL FIDDLE de la question précédente.
J'ai écrit un SELECT
avec un FULL JOIN
Pour atteindre l'objectif de la question référencée. Simplifié:
SELECT ts, f.foo, b.bar
FROM foo f
FULL JOIN bar b USING (ts);
Selon les spécifications, la bonne façon d'adresser la colonne ts
est sans qualification de table. Soit de entrée valeurs (f.ts
ou alors b.ts
) peut être nul. La clause USING
crée un bit d'un cas étrange: introduire une colonne "entrée" qui n'est pas réellement présente dans l'entrée. Jusqu'à présent si élégant.
Je l'ai mis dans une fonction PLPGSQL. Pour plus de commodité (ou exigences), je veux les mêmes noms de colonne pour le résultat de la fonction Table. Nous devons donc éviter de nommer des conflits entre noms de colonnes identiques et paramètres de fonction. Devrait mieux être évité en cueillant des noms différents, mais nous sommes ici:
CREATE OR REPLACE FUNCTION f_merge_foobar()
RETURNS TABLE(ts int, foo text, bar text) AS
$func$
BEGIN
FOR ts, foo, bar IN
SELECT COALESCE(f.ts, b.ts), f.foo, b.bar
FROM foo f
FULL JOIN bar b USING (ts)
LOOP
-- so something
RETURN NEXT;
END LOOP;
END
$func$ LANGUAGE plpgsql;
Soulignez audacieux pour mettre en surbrillance le problème . Je ne peux pas utiliser Sans qualification de table comme avant, car la PLPGSQL souleverait une exception (pas strictement nécessaire, mais probablement utile dans la plupart des cas):ts
ERROR: column reference "ts" is ambiguous LINE 1: SELECT ts, f.foo, b.bar ^ DETAIL: It could refer to either a PL/pgSQL variable or a table column.
Je sais que je peux utiliser des noms différents ou une sous-requête ou utiliser une autre fonction. Mais je me demande s'il y a un moyen de faire référence à la colonne. Je ne peux pas utiliser la qualification de table. On y penserait devrait être un moyen.
Y a-t-il?
Selon les documents PL/PGSQL sous le capot , vous pouvez utiliser le paramètre de configuration plpgsql.variable_conflict
, avant de créer la fonction ou du début de la définition de la fonction, déclarant comment vous voulez que ces conflits soient résolus (les 3 valeurs possibles sont error
(la valeur par défaut ), use_variable
et use_column
):
CREATE OR REPLACE FUNCTION pg_temp.f_merge_foobar()
RETURNS TABLE(ts int, foo text, bar text) AS
$func$
#variable_conflict use_column -- how to resolve conflicts
BEGIN
FOR ts, foo, bar IN
SELECT ts, f.foo, b.bar
FROM foo f
FULL JOIN bar b USING (ts)
LOOP
-- do something
RETURN NEXT;
END LOOP;
END
$func$ LANGUAGE plpgsql;