Najpierw możesz utworzyć VIEW
aby zapewnić tę funkcjonalność:
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;
Możesz sprawdzić ten widok jak każdą inną tabelę:
SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
-
source
jest konieczne, jeśliorder_nr
nie jest wyjątkowy. W jaki inny sposób gwarantowałbyś unikalne numery zamówień z różnych źródeł? -
timestamp without time zone
jest niejednoznaczny w kontekście globalnym. To jest dobre tylko w połączeniu z jego strefą czasową. Jeśli mieszasztimestamp
itimestamptz
, musisz umieścićtimestamp
w określonej strefie czasowej zAT TIME ZONE
konstruktu, aby to zadziałało. Aby uzyskać więcej wyjaśnień, przeczytaj powiązaną odpowiedź .Używam UTC jako strefy czasowej, możesz podać inną. Prosty rzut
"OrderDate"::timestamptz
przyjmie Twoją obecną strefę czasową.AT TIME ZONE
zastosowano dotimestamp
wyniki wtimestamptz
. Dlatego nie dodałem kolejnej obsady. -
Póki możesz , radzę nie używać identyfikatorów wielbłądów w PostgreSQL ever . Unika wielu możliwych pomyłek. Zwróć uwagę na identyfikatory małych liter (bez niepotrzebnych teraz podwójnych cudzysłowów), które podałem.
-
Nie używaj
varchar(25)
jako typ dlaorder_nr
. Po prostu użyjtext
bez modyfikatora dowolnej długości, jeśli ma to być ciąg. Jeśli wszystkie numery zamówień składają się wyłącznie z cyfr,integer
lubbigint
byłoby szybsze.
Wydajność
Jednym ze sposobów, aby to przyspieszyć, byłoby zmaterializowanie widoku. Np. zapisz wynik do (tymczasowej) tabeli:
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);
potrzebujesz indeks. W moim przykładzie ograniczenie klucza podstawowego zapewnia indeks automatycznie.
Jeśli Twoje tabele są duże, upewnij się, że masz wystarczająco dużo buforów tymczasowych obsłużyć to w pamięci RAM przed tworzysz tabelę tymczasową. W przeciwnym razie faktycznie Cię spowolni.
SET temp_buffers = 1000MB;
Musi być pierwszym wywołaniem obiektów tymczasowych w Twojej sesji. Nie ustawiaj go na wysokim poziomie globalnie, tylko na swoją sesję. Tabela tymczasowa i tak jest automatycznie usuwana pod koniec sesji.
Aby uzyskać szacunkową ilość potrzebnej pamięci RAM, utwórz tabelę raz i zmierz:
SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));
Więcej informacji o rozmiarach obiektów znajdziesz w tym pytanie na dba.SE .
Wszystkie koszty ogólne opłacają się tylko wtedy, gdy musisz przetworzyć kilka zapytań w ramach jednej sesji. Dla innych przypadków użycia istnieją inne rozwiązania. Jeśli znasz tabelę źródłową w momencie zapytania, znacznie szybciej byłoby skierować zapytanie do tabeli źródłowej. Jeśli nie, kwestionowałbym wyjątkowość twojego order_nr
jeszcze raz. Jeśli w rzeczywistości gwarantuje się, że jest unikalny, możesz usunąć kolumnę source
przedstawiłem.
W przypadku tylko jednego lub kilku zapytań szybsze może być użycie widoku zamiast widoku zmaterializowanego.
Rozważyłbym również funkcję plpgsql który wykonuje zapytania jedną tabelę po drugiej, aż do znalezienia rekordu. Może być tańsze w przypadku kilku zapytań, biorąc pod uwagę obciążenie. Oczywiście indeksy dla każdej tabeli.
Ponadto, jeśli trzymasz się text
lub varchar
dla Twojego order_nr
, rozważ COLLATE "C"
za to.