1

これはearlier oneへのフォローアップの質問です。私は2つの引数を取るストアドファンクションf1を持っていますが、5つのカラムを持つテーブルが返されます。今のところ返される値は定数で、後で引数から計算されます。VIEW定義で「ERROR:列...複数回指定」

f1の引数に対応する2つの列を持つテーブルt1もあります。

t1に格納されているすべての引数ペアについて、f1から返されたすべての行の和集合を含むビューv1を定義します。与えられた例のための結果であるべき値:も罰金であろう最初の2つの列が剥奪されている場合

+---+---+---+---+---+---+---+ 
| 2 | 3 | a | b | 1 | c | d | 
+---+---+---+---+---+---+---+ 
| 4 | 5 | a | b | 1 | c | d | 
+---+---+---+---+---+---+---+ 

、。 f1は、特定の引数値に対して複数の行を返す可能性があることに注意してください。

私は、次のステートメントを試してみたが、それは私にこのエラーメッセージが表示できます:私は間違って何をやっている

ERROR: column "c4" specified more than once 
CREATE VIEW v1 (c1, c2, c3, c4, c5) 
AS SELECT * FROM 
    (SELECT c1, c2 FROM t1) AS x, 
    f1 (x.c1, x.c2); 

を?ここで

は例を設定するには、前の文です:

CREATE OR REPLACE FUNCTION f1 (a1 INTEGER, a2 INTEGER) 
RETURNS TABLE (c1 VARCHAR(20), c2 VARCHAR(20), c3 INTEGER, c4 VARCHAR(20), c5 VARCHAR(128)) 
AS $$ 
SELECT 'a'::VARCHAR(20), 'b'::VARCHAR(20), 1::INTEGER, 'c'::VARCHAR(20), 'd'::VARCHAR(128); 
$$ LANGUAGE SQL; 

DROP TABLE IF EXISTS t1; 
CREATE TABLE t1 (c1 INTEGER, c2 INTEGER); 
INSERT INTO t1 (c1, c2) 
VALUES (2,3), (4,5); 

DROP VIEW IF EXISTS v1; 
+1

は '' *選択し、使用しないでください - 代わりにあなたが必要なフィールドを選択します。つまり、 'c1'は' f1'と 't1'の両方に存在します... – sgeddes

+0

@sgeddes私はそれを試みますが、エラーメッセージは' c4'を引用します。優れたPostgreSQLの回答、こちら – Drux

答えて

1

私はLATERALSELECTクエリに参加をお勧め:

CREATE VIEW v1 AS 
SELECT f.* 
FROM t1 
    , f1 (t1.c1, t1.c2) AS f; -- implicit CROSS JOIN LATERAL 

関数定義で定義された列名がすでに一致しているのでまた、ビュー定義から列名を削除することもできます。

ビューを作成すると、の初期バインディングと動作します。つまり、作成時に選択された列のみがビューに含まれます。後で追加の列を返すように関数定義を変更すると、ビューにはではなくが含まれます。 (あなたが列を削除または名前変更した場合、ビューを破る。)

あなたはほとんど同じ効果に、SELECTリスト中の集合を返す関数f1(..)を含めることができます。違い:SELECTリストで

  • 集合を返す関数は、SQL標準に違反し、いくつかによって眉をひそめるされています。また、他のRDBMSに移植することもできません。 PostgresはPostgres 9.3で(標準SQL)LATERALを導入して以来、一般的にはそれが望ましいです。

  • SELECTリスト(有効相関サブクエリ)において集合を返す関数は、関数が任意の行を返さない場合でも、LEFT JOIN LATERAL ... ON trueの等価、すなわち、それはt1のすべての行を保持しています。 CROSS JOIN LATERALが上記のように行を削除します。ここで、f1()は行を返しません。

  • あなたSELECT (f1(...)).*, ...と関数から返された、明確に定義された行の種類を分解することができるが、関数ではなく一度だけの戻り型の列ごとに繰り返し評価することができます。

関連し、より詳細:

+0

優れています。 (急いでPostgreSQLを再学習する... ;-) – Drux

関連する問題