Dada esta configuração no Postgres 9.4 atual ( desta pergunta 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');
Há também um SQL Fiddle da pergunta anterior.
Eu escrevi a SELECT
com a FULL JOIN
para atingir o objetivo da pergunta referenciada. Simplificado:
SELECT ts, f.foo, b.bar
FROM foo f
FULL JOIN bar b USING (ts);
De acordo com as especificações, a maneira correta de abordar a coluna ts
é sem qualificação da tabela. Qualquer um dos valores de entrada ( f.ts
ou b.ts
) pode ser NULL. A USING
cláusula cria um caso um tanto estranho: a introdução de uma coluna "input" que não está realmente presente na entrada. Até agora, tão elegante.
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, temos que evitar conflitos de nomeação entre nomes de colunas idênticos e parâmetros de função. Deve ser evitado escolhendo nomes diferentes, mas aqui estamos:
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;
Negrito ênfase para destacar o problema . Não posso usar sem a qualificação da tabela como antes, porque o 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.
Eu sei que posso usar nomes diferentes ou uma subconsulta ou usar outra função. Mas eu me pergunto se existe uma maneira de fazer referência à coluna. Não posso usar a qualificação de tabela. Alguém poderia pensar que deveria haver um caminho.
Existe?
fonte