Първо, можете да създадете 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"
за това.