PostgreSQLは、MS SQL Serverなどの計算列/計算列をサポートしていますか?ドキュメントには何も見つかりませんが、この機能は他の多くのDBMSに含まれているので、何かが足りないと思っていました。
SQL標準で定義され、DB2、MySQL、Oracleなどの一部のRDBMSで実装されているように、Postgres 11で生成された列はサポートされていません。 SQL Serverの同様の"計算列"もありません。
STORED
生成列は、Postgres 12で導入されます。簡単な例:
CREATE TABLE tbl (
int1 int
, int2 int
, product bigint GENERATED ALWAYS AS (int1 * int2) STORED
);
db <> fiddle here
VIRTUAL
で生成された列は、次の反復で使用される場合があります。関連する:
それまでまで、属性表記を使用して、関数でVIRTUAL
生成列をエミュレートできます=(tbl.col
)は、仮想生成列のように見え、動作します。これは歴史的な理由でPostgresに存在するちょっとした構文の奇妙さであり、偶然にもケースに適合します。この関連する回答には、コード例があります:
ただし、式(列のように見える)はSELECT * FROM tbl
には含まれません。常に明示的にリストする必要があります。
一致する expression index でサポートすることもできます-関数がIMMUTABLE
である場合。好む:
CREATE FUNCTION col(tbl) ... AS ... -- your computed expression here
CREATE INDEX ON tbl(col(tbl));
あるいは、 VIEW
を使用して同様の機能を実装し、オプションで式インデックスと組み合わせることもできます。次に、SELECT *
に生成された列を含めることができます。
「永続」(STORED
)計算列は、機能的に同じ方法で triggers で実装できます。
マテリアライズドビュー は密接に関連する概念です。 Postgres 9.3以降で実装 。
以前のバージョンでは、MVを手動で管理できました。
はい、できます!!解決策は簡単、安全、そして高性能でなければなりません...
私はpostgresqlを初めて使用しますが、 expression index と組み合わせて view を使用して計算列を作成できるようです(ビューはオプションですが、少し簡単)。
私の計算がmd5(some_string_field)
であるとすると、次のようにインデックスを作成します:
_CREATE INDEX some_string_field_md5_index ON some_table(MD5(some_string_field));
_
現在、MD5(some_string_field)
に作用するクエリは、インデックスを最初から計算するのではなく、インデックスを使用します。例えば:
_SELECT MAX(some_field) FROM some_table GROUP BY MD5(some_string_field);
_
これは explain で確認できます。
ただし、この時点では、列の作成方法を正確に知っているテーブルのユーザーに依存しています。作業を簡単にするために、元のテーブルの拡張バージョンにVIEW
を作成し、計算された値を新しい列として追加できます。
_CREATE VIEW some_table_augmented AS
SELECT *, MD5(some_string_field) as some_string_field_md5 from some_table;
_
これで、_some_table_augmented
_を使用するクエリは、_some_string_field_md5
_を使用できます。どのように動作するかを心配することなく、それらは良好なパフォーマンスを得るだけです。ビューは元のテーブルからデータをコピーしないため、パフォーマンス面でもメモリ面でも優れています。ただし、ビューへの更新/挿入はできず、ソーステーブルのみにできますが、本当に必要な場合は、 rules を使用してソーステーブルへの挿入と更新をリダイレクトできると思います私は自分で試したことがないので、その最後の点で間違っている)。
編集:クエリに競合するインデックスが含まれている場合、プランナエンジンはexpression-indexをまったく使用しない場合があります。選択はデータに依存しているようです。
これを行う1つの方法は、トリガーを使用することです!
CREATE TABLE computed(
one SERIAL,
two INT NOT NULL
);
CREATE OR REPLACE FUNCTION computed_two_trg()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
AS $BODY$
BEGIN
NEW.two = NEW.one * 2;
RETURN NEW;
END
$BODY$;
CREATE TRIGGER computed_500
BEFORE INSERT OR UPDATE
ON computed
FOR EACH ROW
EXECUTE PROCEDURE computed_two_trg();
行が更新または挿入される前にトリガーが起動されます。 NEW
レコードの計算するフィールドを変更し、そのレコードを返します。
PostgreSQL 12は生成列をサポートします:
生成された列
PostgreSQL 12では、他の列の内容を使用した式で値を計算する生成列を作成できます。この機能は、挿入と更新で計算され、ディスクに保存される生成済み列を提供します。列がクエリの一部として読み取られる場合にのみ計算される仮想生成列は、まだ実装されています。
生成された列は、常に他の列から計算される特別な列です。したがって、テーブル用のビューは列用です。
CREATE TABLE people (
...,
height_cm numeric,
height_in numeric GENERATED ALWAYS AS (height_cm * 2.54) STORED
);
動作するコードを使用して計算された用語を使用していますが、PADBで実行するpostgresSQL純粋なものではありません
使用方法は次のとおりです
create table some_table as
select category,
txn_type,
indiv_id,
accum_trip_flag,
max(first_true_Origin) as true_Origin,
max(first_true_dest ) as true_destination,
max(id) as id,
count(id) as tkts_cnt,
(case when calculated tkts_cnt=1 then 1 else 0 end) as one_way
from some_rando_table
group by 1,2,3,4 ;