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 blandartimestampochtimestamptzmåste du placeratimestampvid en viss tidszon medAT TIME ZONEbygga 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"::timestamptzskulle anta din nuvarande tidszon.AT TIME ZONEtillämpas på entimestampresulterar 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 baratextutan godtycklig längdmodifierare om det måste vara en sträng. Om alla ordernummer uteslutande består av siffror,integerellerbigintskulle 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.