Първо, можете да създадете VIEW
за предоставяне на тази функционалност:
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;
Можете да направите запитване към този изглед като всяка друга таблица:
SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
-
source
е необходимо, акоorder_nr
не е уникален. Как иначе бихте гарантирали уникални номера на поръчки от различни източници? -
timestamp without time zone
е двусмислен в глобален контекст. Добър е само във връзка с часовата си зона. Ако смеситеtimestamp
иtimestamptz
, трябва да поставитеtimestamp
в определена часова зона сAT TIME ZONE
конструкция, за да направи тази работа. За повече обяснение прочетете този свързан отговор .Използвам UTC като часова зона, може да искате да предоставите друга. Просто преобразуване
"OrderDate"::timestamptz
ще приеме текущата ви часова зона.AT TIME ZONE
приложен къмtimestamp
води доtimestamptz
. Ето защо не добавих друг актьорски състав. -
Докато можете , съветвам ви да не използвате идентификатори с камилски регистър в PostgreSQL никога . Избягва много видове възможни обърквания. Обърнете внимание на идентификаторите с малки букви (без вече ненужните двойни кавички), които предоставих.
-
Не използвайте
varchar(25)
като тип заorder_nr
. Просто използвайтеtext
без модификатор на произволна дължина, ако трябва да бъде низ. Ако всички номера на поръчки се състоят само от цифри,integer
илиbigint
би било по-бързо.
Ефективност
Един от начините да направите това бързо е да материализирате гледката. Т.е. запишете резултата във (временна) таблица:
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);
Вие трябвате индекс. В моя пример ограничението на първичния ключ предоставя индекса автоматично.
Ако масите ви са големи, уверете се, че имате достатъчно временни буфери за да се справи с това в RAM преди създавате временната таблица. В противен случай всъщност ще ви забави.
SET temp_buffers = 1000MB;
Трябва да е първото извикване на временни обекти във вашата сесия. Не го задавайте високо глобално, само за вашата сесия. Така или иначе временна таблица се премахва автоматично в края на вашата сесия.
За да получите оценка колко RAM ви е необходима, създайте таблицата веднъж и измерете:
SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));
Повече за размерите на обектите под този свързан въпрос на dba.SE .
Всички режийни разходи се плащат само ако трябва да обработите определен брой заявки в рамките на една сесия. За други случаи на употреба има други решения. Ако знаете изходната таблица по време на заявката, би било много по-бързо вместо това да насочите заявката си към изходната таблица. Ако не го направите, бих поставил под въпрос уникалността на вашия order_nr
още веднъж. Ако всъщност е гарантирано, че е уникален, можете да изпуснете колоната source
Представих.
Само за една или няколко заявки може да е по-бързо да използвате изгледа вместо материализирания изглед.
Бих обмислил и функция plpgsql който прави заявки една след друга таблица, докато не бъде намерен записът. Може да е по-евтино за няколко запитвания, като се имат предвид режийните разходи. Разбира се, необходими са индекси за всяка таблица.
Освен това, ако се придържате към text
или varchar
за вашия order_nr
, помислете за COLLATE "C"
за това.