Berechnete / berechnete Spalten in PostgreSQL

Unterstützt PostgreSQL berechnete / berechnete Spalten wie MS SQL Server? Ich kann nichts in den Dokumenten finden, aber da diese function in vielen anderen DBMS enthalten ist, dachte ich, ich könnte etwas verpassen.

ZB: http://msdn.microsoft.com/en-us/library/ms191250.aspx

   

    PostgreSQL unterstützt “Berechnete Spalten” per se nicht bis mindestens Postgres 11.

    Siehe den Kommentar von f90t zu dem Feature, das gerade entwickelt wird. Aber es scheint noch nicht so, als ob es in Postgres 11 sein wird.

    Sie können ähnliche functionen mit einer Ansicht implementieren.

    Oder Sie können functionen verwenden, die genauso funktionieren wie berechnete Spalten .
    Detaillierte Erklärung in dieser verwandten Antwort:

    • Gemeinsame Abfrage als Spalte speichern?

    “Persistent” berechnete Spalten können mit Triggern funktional identisch implementiert werden.

    Materialisierte Views sind ein eng verwandtes Konzept, das seit Postgres 9.3 implementiert wurde .
    In früheren Versionen kann man MVs manuell verwalten.

    Eine Möglichkeit, dies zu tun, ist mit einem Trigger!

    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(); 

    Der Trigger wird ausgetriggers, bevor die Zeile aktualisiert oder eingefügt wird. Es ändert das Feld, das wir von NEW Datensatz berechnen möchten, und dann gibt es diesen Datensatz zurück.

    Ja, du kannst!! Die Lösung sollte einfach, sicher und leistungsfähig sein …

    Ich bin neu bei Postgresql, aber es scheint, dass Sie berechnete Spalten erstellen können, indem Sie einen Ausdrucksindex verwenden , gepaart mit einer Ansicht (die Ansicht ist optional, macht aber das Leben ein bisschen leichter).

    Angenommen, meine Berechnung ist md5(some_string_field) , dann erstelle ich den Index als:

     CREATE INDEX some_string_field_md5_index ON some_table(MD5(some_string_field)); 

    Nun werden alle Abfragen, die auf MD5(some_string_field) , den Index verwenden, anstatt ihn von Grund auf neu zu berechnen. Beispielsweise:

     SELECT MAX(some_field) FROM some_table GROUP BY MD5(some_string_field); 

    Sie können dies mit erklären überprüfen.

    An dieser Stelle verlassen Sie sich jedoch darauf, dass die Benutzer der Tabelle genau wissen, wie die Spalte aufgebaut wird. Um das Leben einfacher zu machen, können Sie eine VIEW auf eine erweiterte Version der ursprünglichen Tabelle erstellen und den berechneten Wert als neue Spalte hinzufügen:

     CREATE VIEW some_table_augmented AS SELECT *, MD5(some_string_field) as some_string_field_md5 from some_table; 

    Jetzt können alle Abfragen, die some_table_augmented verwenden, some_string_field_md5 ohne sich Gedanken darüber machen zu müssen, wie es funktioniert. Sie erhalten nur eine gute performance. Die Ansicht kopiert keine Daten aus der Originaltabelle, daher ist sie sowohl speicher- als auch leistungsmäßig gut. Beachten Sie jedoch, dass Sie in einer Ansicht nur in die Quelltabelle aktualisieren / einfügen können, aber wenn Sie das wirklich wollen, können Sie Einfügungen und Aktualisierungen nach der Regel in die Quelltabelle redirect (ich könnte bei diesem letzten Punkt falsch liegen) Ich habe es nie selbst ausprobiert).

    Edit: Es scheint, wenn die Abfrage konkurrierende Indizes enthält, kann die Planer-Engine manchmal den Ausdruck-Index überhaupt nicht verwenden. Die Wahl scheint datenabhängig zu sein.

    Ich habe einen Code, der funktioniert und den Begriff berechnet, ich bin nicht auf PostgresSQL rein, dass wir auf PADB laufen

    Hier ist, wie es benutzt wird

     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 ; 

    Eine leichte Lösung mit Check constraint:

     CREATE TABLE example ( discriminator INTEGER DEFAULT 0 NOT NULL CHECK (discriminator = 0) );