現在のPostgres 9.4でのこのセットアップを考えると(この関連する質問から):
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');
前の質問からのSQL Fiddleもあります。
私が書いたSELECT
とをFULL JOIN
参照し、質問の目的を達成するために。簡略化:
SELECT ts, f.foo, b.bar
FROM foo f
FULL JOIN bar b USING (ts);
仕様に従って、列をアドレス指定する正しい方法ts
は、テーブル修飾なしです。入力値(f.ts
またはb.ts
)のいずれかをNULLにすることができます。このUSING
句は、奇妙なケースを少し作成します。実際には入力に存在しない「入力」列を導入します。これまでのところとてもエレガント。
これをplpgsql関数に入れました。便宜上(または要件)、表関数の結果に同じ列名が必要です。したがって、同一の列名と関数パラメーター間の名前の競合を避ける必要があります。別の名前を選択することで回避するのが最善ですが、ここでは次のとおりです。
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;
問題を強調するための大胆な強調。plpgsqlは例外を発生させるため(厳密には必要ではありませんが、ほとんどの場合に役立つ可能性があります)、以前のようにテーブル修飾なしで使用することはできません。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.
別の名前やサブクエリを使用したり、別の関数を使用したりできることを知っています。しかし、列を参照する方法があるのだろうか。テーブル修飾を使用できません。方法があるはずだと思うでしょう。
ある?