问题
I have two tables that have identical columns. I would like to join these two tables together into a third one that contains all the rows from the first one and from the second one all the rows that have a date that doesn't exist in the first table for the same location.
Example:
transactions:
date |location_code| product_code | quantity
------------+------------------+--------------+----------
2013-01-20 | ABC | 123 | -20
2013-01-23 | ABC | 123 | -13.158
2013-02-04 | BCD | 234 | -4.063
transactions2:
date |location_code| product_code | quantity
------------+------------------+--------------+----------
2013-01-20 | BDE | 123 | -30
2013-01-23 | DCF | 123 | -2
2013-02-05 | UXJ | 234 | -6
Desired result:
date |location_code| product_code | quantity
------------+------------------+--------------+----------
2013-01-20 | ABC | 123 | -20
2013-01-23 | ABC | 123 | -13.158
2013-01-23 | DCF | 123 | -2
2013-02-04 | BCD | 234 | -4.063
2013-02-05 | UXJ | 234 | -6
How would I go about this? I tried for example this:
SELECT date, location_code, product_code, type, quantity, location_type, updated_at
,period_start_date, period_end_date
INTO transactions_combined
FROM ( SELECT * FROM transactions_kitchen k
UNION ALL
SELECT *
FROM transactions_admin h
WHERE h.date NOT IN (SELECT k.date FROM k)
) AS t;
but that doesn't take into account that I'd like to include the rows that have the same date, but different location. I have Postgresql 9.2 in use.
回答1:
According to your description, the query could look like this:
I use LEFT JOIN / IS NULL to exclude rows from the second table for the same location and date. NOT EXISTS would be the other good option.UNION simply doesn't do what you describe.
CREATE TABLE AS
SELECT date, location_code, product_code, quantity
FROM transactions_kitchen k
UNION ALL
SELECT h.date, h.location_code, h.product_code, h.quantity
FROM transactions_admin h
LEFT JOIN transactions_kitchen k USING (location_code, date)
WHERE k.location_code IS NULL;
Use CREATE TABLE AS instead of SELECT INTO.
I quote the manual on SELECT INTO:
CREATE TABLE ASis functionally similar toSELECT INTO.CREATE TABLE ASis the recommended syntax, since this form ofSELECT INTOis not available in ECPG or PL/pgSQL, because they interpret theINTOclause differently. Furthermore,CREATE TABLE ASoffers a superset of the functionality provided bySELECT INTO.
Or, if the target table already exists:
INSERT INTO transactions_combined (<list names of target column here!>)
SELECT ...
I would advise not to use date as column name. It's a reserved word in every SQL standard and a function and data type name in PostgreSQL.
回答2:
Change UNION ALL to just UNION and it should return only unique rows from each table.
来源:https://stackoverflow.com/questions/15559090/combine-two-tables-into-a-new-one-so-that-select-rows-from-the-other-one-are-ign