Dada esta configuração no Postgres 9.4 atual ( desta questão relacionada ):
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');
db<>fiddle aqui (também da pergunta anterior).
Escrevi a SELECT
com a FULL JOIN
para atingir o objetivo da questão referenciada. Simplificado:
SELECT ts, f.foo, b.bar
FROM foo f
FULL JOIN bar b USING (ts);
Conforme especificações, a forma correta de endereçar a coluna ts
é sem qualificação de tabela. Qualquer um dos valores de entrada ( f.ts
ou b.ts
) pode ser NULL. A USING
cláusula cria um caso estranho: introduzir uma coluna de "entrada" que não está realmente presente na entrada. Até agora tão elegante.
Eu coloquei isso em uma função plpgsql. Por conveniência (ou requisitos), quero os mesmos nomes de coluna para o resultado da função de tabela. Portanto, devemos evitar conflitos de nomenclatura entre nomes de colunas e parâmetros de função idênticos. Deve ser evitado escolhendo nomes diferentes, mas aqui estamos:
CREATE OR REPLACE FUNCTION f_merge_foobar()
RETURNS TABLE(ts int, foo text, bar text)
LANGUAGE plpgsql 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$;
Ênfase em negrito para destacar o problema . Não posso usar sem qualificação de tabela como antes, porque plpgsql geraria uma exceção (não estritamente necessária, mas provavelmente útil na maioria dos casos):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.
Sei que posso usar nomes diferentes ou uma subconsulta ou usar outra função. Mas eu me pergunto se há uma maneira de referenciar a coluna. Não consigo usar a qualificação de tabela. Alguém poderia pensar que deveria haver uma maneira.
Existe?
De acordo com a documentação PL/pgSQL Under the Hood , você pode usar o parâmetro de configuração
plpgsql.variable_conflict
, antes de criar a função ou no início da definição da função, declarando como deseja que tais conflitos sejam resolvidos.As 3 configurações possíveis são
error
(o padrão)use_variable
euse_column
:O Postgres 14 adiciona a sintaxe SQL para resolver esse problema. Agora você pode anexar uma
AS
cláusula para declarar um novo alias de tabela para as colunas mescladas naUSING
lista:O manual: