Primero, puede crear un VIEW
para proporcionar esta funcionalidad:
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;
Puede consultar esta vista como cualquier otra tabla:
SELECT * FROM orders WHERE order_nr = 123 AND source = 2;
-
La
source
es necesario si elorder_nr
no es único ¿De qué otra forma garantizaría números de pedido únicos en diferentes fuentes? -
Una
timestamp without time zone
es ambiguo en un contexto global. Solo es bueno en relación con su zona horaria. Si mezclastimestamp
ytimestamptz
, debe colocar latimestamp
en una determinada zona horaria con elAT TIME ZONE
construir para hacer este trabajo. Para obtener más explicaciones, lea esta respuesta relacionada .Uso UTC como zona horaria, es posible que desee proporcionar una diferente. Un lanzamiento simple
"OrderDate"::timestamptz
asumiría su zona horaria actual.AT TIME ZONE
aplicado a unatimestamp
da como resultadotimestamptz
. Es por eso que no agregué otro elenco. -
Mientras puedas , aconsejo no usar identificadores camel-case en PostgreSQL nunca . Evita muchos tipos de posibles confusiones. Tenga en cuenta los identificadores en minúsculas (sin las ahora innecesarias comillas dobles) que proporcioné.
-
No use
varchar(25)
como tipo para elorder_nr
. Solo usatext
sin modificador de longitud arbitrario si tiene que ser una cadena. Si todos los números de pedido consisten exclusivamente en dígitos,integer
obigint
sería más rápido.
Rendimiento
Una forma de hacer esto rápido sería materializar la vista. Es decir, escriba el resultado en una tabla (temporal):
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);
Usted necesita un índice. En mi ejemplo, la restricción de clave principal proporciona el índice automáticamente.
Si sus tablas son grandes, asegúrese de tener suficientes búferes temporales para manejar esto en RAM antes creas la tabla temporal. De lo contrario, te retrasará.
SET temp_buffers = 1000MB;
Tiene que ser la primera llamada a objetos temporales en su sesión. No lo establezca alto globalmente, solo para su sesión. Una tabla temporal se elimina automáticamente al final de su sesión de todos modos.
Para obtener una estimación de la cantidad de RAM que necesita, cree la tabla una vez y mida:
SELECT pg_size_pretty(pg_total_relation_size('tmp_orders'));
Más información sobre los tamaños de los objetos en esta pregunta relacionada en dba.SE .
Todos los gastos generales solo se pagan si tiene que procesar varias consultas en una sesión. Para otros casos de uso hay otras soluciones. Si conoce la tabla de origen en el momento de la consulta, sería mucho más rápido dirigir su consulta a la tabla de origen. Si no lo hace, cuestionaría la singularidad de su order_nr
una vez más. Si, de hecho, está garantizado que es único, puede eliminar la columna source
Yo presenté.
Para solo una o algunas consultas, podría ser más rápido usar la vista en lugar de la vista materializada.
También consideraría una función plpgsql que consulta una tabla tras otra hasta que se encuentra el registro. Podría ser más barato para un par de consultas, teniendo en cuenta los gastos generales. Por supuesto, se necesitan índices para cada tabla.
Además, si te limitas a text
o varchar
para su order_nr
, considere COLLATE "C"
por ello.