その副選択を疑似列としてテーブルに保存する方法はありますか?
VIEW
アドバイスされているように、完全に有効な解決策です。頑張ってください。
しかし、あなたの質問にさらにぴったり合う別の方法があります。テーブルタイプをパラメータとして受け取る関数を記述して、エミュレートすることができます。 「計算フィールド」 または「生成された列」 。
あなたの説明から導き出されたこのテストケースを考えてみましょう:
CREATE TABLE tbl_a (a_id int, col1 int, col2 int);
INSERT INTO tbl_a VALUES (1,1,1), (2,2,2), (3,3,3), (4,4,4);
CREATE TABLE tbl_b (b_id int, a_id int, colx int);
INSERT INTO tbl_b VALUES
(1,1,5), (2,1,5), (3,1,1)
, (4,2,8), (5,2,8), (6,2,6)
, (7,3,11), (8,3,11), (9,3,11);
col3
をエミュレートする関数を作成します :
CREATE FUNCTION col3(tbl_a)
RETURNS int8
LANGUAGE sql STABLE AS
$func$
SELECT sum(colx)
FROM tbl_b b
WHERE b.a_id = $1.a_id
$func$;
これで、クエリを実行できます:
SELECT a_id, col1, col2, tbl_a.col3
FROM tbl_a;
または:
SELECT *, a.col3 FROM tbl_a a;
tbl_a.col3
の書き方に注意してください / a.col3
、col3
だけではありません 。これは必須です 。
Oracleの「仮想列」とは異なり、そうではありません SELECT * FROM tbl_a
に自動的に含まれます 。 VIEW
を使用できます そのために。
なぜこれが機能するのですか?
テーブル列を参照する一般的な方法は、属性表記を使用することです。 :
SELECT tbl_a.col1 FROM tbl_a;
関数を呼び出す一般的な方法は、関数表記を使用することです。 :
SELECT col3(tbl_a);
一般的に、これらの標準的な方法に固執するのが最善です。 、SQL標準に同意します。
ただし、Postgresでは属性表記も使用できます。これらも機能します:
SELECT col1(tbl_a) FROM tbl_a; SELECT tbl_a.col3;
詳細については、マニュアルをご覧ください。
これがどこに向かっているのかは、おそらく今ではわかります。この見た目 テーブルtbl_a
の列を追加するように col3()
実際には、tbl_a
の現在の行を取得する関数です。 (またはそのエイリアス)を行タイプの引数として使用し、値を計算します。
SELECT *, a.col3
FROM tbl_a AS a;
実際の列がある場合col3
これが優先され、システムは行tbl_a
を取得するその名前の関数を検索しません。 パラメータとして。
その「美しさ」:tbl_a
から列を追加または削除できます 最後のクエリは、現在のすべての列を動的に返します。ビューは、作成時に存在した列のみを返します(*
のアーリーバインディングとレイトバインディング。 )。
もちろん、テーブルをドロップする前に、依存する関数をドロップする必要があります。また、テーブルに変更を加えるときは、関数を無効にしないように注意する必要があります。
私はまだそれを使用しません。罪のない読者には驚きすぎます。