Zuerst können Sie eine VIEW
erstellen
um diese Funktionalität bereitzustellen:
CREATE VIEW orders AS
SELECT '1'::int AS source -- or any other tag to identify source
,"OrderNumber"::text AS order_nr
,"InvoiceNumber" AS tansaction_id -- no cast .. is int already
,"OrderDate" AT TIME ZONE 'UTC' AS purchase_date -- !! see explanation
FROM tbl_newegg
UNION ALL -- not UNION!
SELECT 2
"amazonOrderId"
,"merchant-order-id"
,"purchase-date"
FROM tbl_amazon;
Sie können diese Ansicht wie jede andere Tabelle abfragen:
SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
-
Die
source
ist erforderlich, wenn dieorder_nr
ist nicht einzigartig. Wie sonst würden Sie eindeutige Bestellnummern über verschiedene Quellen hinweg garantieren? -
Ein
timestamp without time zone
ist im globalen Kontext mehrdeutig. Es ist nur in Verbindung mit seiner Zeitzone gut. Wenn Sietimestamp
mischen undtimestamptz
, müssen Sie dentimestamp
platzieren zu einer bestimmten Zeitzone mit demAT TIME ZONE
konstruieren, damit dies funktioniert. Für weitere Erklärungen lesen Sie diese verwandte Antwort .Ich verwende UTC als Zeitzone, vielleicht möchten Sie eine andere angeben. Ein einfacher Cast
"OrderDate"::timestamptz
würde Ihre aktuelle Zeitzone annehmen.AT TIME ZONE
angewendet auf einentimestamp
ergibttimestamptz
. Deshalb habe ich keinen weiteren Cast hinzugefügt. -
Solange Sie können , rate ich davon ab, Camel-Case-Identifikatoren in PostgreSQL niemals zu verwenden . Vermeidet viele Arten möglicher Verwirrung. Beachten Sie die von mir bereitgestellten Bezeichner in Kleinbuchstaben (ohne die jetzt unnötigen doppelten Anführungszeichen).
-
Verwenden Sie
varchar(25)
nicht als Typ für dieorder_nr
. Verwenden Sie einfachtext
ohne beliebigen Längenmodifikator, wenn es ein String sein muss. Wenn alle Bestellnummern ausschließlich aus Ziffern bestehen,integer
oderbigint
wäre schneller.
Leistung
Eine Möglichkeit, dies schnell zu machen, wäre, die Ansicht zu materialisieren. D.h. das Ergebnis in eine (temporäre) Tabelle schreiben:
CREATE TEMP TABLE tmp_orders AS
SELECT * FROM orders;
ANALYZE tmp_orders; -- temp tables are not auto-analyzed!
ALTER TABLE tmp_orders
ADD constraint orders_pk PRIMARY KEY (order_nr, source);
Sie brauchen ein Index. In meinem Beispiel liefert die Primärschlüssel-Einschränkung den Index automatisch.
Wenn Ihre Tabellen groß sind, stellen Sie sicher, dass Sie genügend temporäre Puffer haben um dies im RAM vorher zu handhaben Sie erstellen die temporäre Tabelle. Andernfalls wird es Sie tatsächlich verlangsamen.
SET temp_buffers = 1000MB;
Muss der erste Aufruf von temporären Objekten in Ihrer Sitzung sein. Stellen Sie es nicht global hoch ein, nur für Ihre Sitzung. Eine temporäre Tabelle wird am Ende Ihrer Sitzung sowieso automatisch gelöscht.
Um abzuschätzen, wie viel RAM Sie benötigen, erstellen Sie die Tabelle einmal und messen Sie:
SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));
Mehr zu Objektgrößen unter dieser verwandten Frage zu dba.SE .
Der gesamte Aufwand zahlt sich nur aus, wenn Sie mehrere Abfragen innerhalb einer Sitzung verarbeiten müssen. Für andere Anwendungsfälle gibt es andere Lösungen. Wenn Sie die Quelltabelle zum Zeitpunkt der Abfrage kennen, wäre es viel schneller, Ihre Abfrage stattdessen an die Quelltabelle zu richten. Wenn Sie dies nicht tun, würde ich die Eindeutigkeit Ihrer order_nr
in Frage stellen einmal mehr. Wenn die Eindeutigkeit garantiert ist, können Sie die Spalte source
weglassen Ich habe vorgestellt.
Für nur eine oder wenige Abfragen kann es schneller sein, die Ansicht anstelle der materialisierten Ansicht zu verwenden.
Ich würde auch eine plpgsql-Funktion in Betracht ziehen die eine Tabelle nach der anderen abfragt, bis der Datensatz gefunden ist. Könnte für ein paar Abfragen billiger sein, wenn man den Overhead berücksichtigt. Indizes für jede benötigte Tabelle natürlich.
Auch, wenn Sie sich an text
halten oder varchar
für Ihre order_nr
, betrachten Sie COLLATE "C"
dafür.