Först kan du skapa en VIEW
för att tillhandahålla denna funktionalitet:
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;
Du kan fråga den här vyn som vilken annan tabell som helst:
SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
-
source
är nödvändigt omorder_nr
är inte unik. Hur skulle du annars garantera unika ordernummer över olika källor? -
En
timestamp without time zone
är en tvetydig i ett globalt sammanhang. Det är bara bra i samband med sin tidszon. Om du blandartimestamp
ochtimestamptz
måste du placeratimestamp
vid en viss tidszon medAT TIME ZONE
bygga för att få detta att fungera. För mer förklaring läs det här relaterade svaret .Jag använder UTC som tidszon, du kanske vill ange en annan. En enkel cast
"OrderDate"::timestamptz
skulle anta din nuvarande tidszon.AT TIME ZONE
tillämpas på entimestamp
resulterar itimestamptz
. Det var därför jag inte lade till ytterligare en skådespelare. -
Medan du kan , Jag rekommenderar att du inte använder kamel-case-identifierare i PostgreSQL någonsin . Undviker många typer av möjlig förvirring. Notera de gemener (utan de nu onödiga citattecken) som jag angav.
-
Använd inte
varchar(25)
som typ förorder_nr
. Använd baratext
utan godtycklig längdmodifierare om det måste vara en sträng. Om alla ordernummer uteslutande består av siffror,integer
ellerbigint
skulle vara snabbare.
Prestanda
Ett sätt att göra detta snabbt skulle vara att materialisera utsikten. Dvs skriv in resultatet i en (tillfällig) tabell:
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);
Du behöver ett index. I mitt exempel tillhandahåller primärnyckelbegränsningen indexet automatiskt.
Om dina bord är stora, se till att du har tillräckligt med tillfälliga buffertar att hantera detta i RAM före du skapar temptabellen. Annars kommer det faktiskt att sakta ner dig.
SET temp_buffers = 1000MB;
Måste vara det första anropet till tillfälliga objekt i din session. Sätt inte det högt globalt, bara för din session. En temporär tabell tas bort automatiskt i slutet av din session i alla fall.
För att få en uppskattning av hur mycket RAM-minne du behöver, skapa tabellen en gång och mät:
SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));
Mer om objektstorlekar under denna relaterade fråga på dba.SE .
All overhead betalar sig bara om du måste behandla ett antal frågor inom en session. För andra användningsfall finns det andra lösningar. Om du känner till källtabellen vid tidpunkten för frågan, skulle det vara mycket snabbare att rikta din fråga till källtabellen istället. Om du inte gör det skulle jag ifrågasätta det unika med din order_nr
en gång till. Om det faktiskt är garanterat unikt kan du släppa kolumnen source
Jag presenterade.
För bara en eller några få frågor kan det vara snabbare att använda vyn istället för den materialiserade vyn.
Jag skulle också överväga en plpgsql-funktion som frågar den ena tabellen efter den andra tills posten hittas. Kan vara billigare för ett par frågor, med tanke på omkostnader. Index för varje tabell som behövs såklart.
Dessutom, om du håller dig till text
eller varchar
för din order_nr
, överväg COLLATE "C"
för det.