将两个表组合成一个新表,以便忽略另一个表中的选择行

时间:2013-03-21 22:04:55

标签: sql postgresql duplicates left-join union

我有两个具有相同列的表。我想将这两个表连接成第三个表,其中包含第一个表中的所有行,第二个表中包含第一个表中不存在的相同位置的所有行。

示例:

交易:

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

期望的结果:

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

我该怎么做?我试过这个例子:

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;

但是这并没有考虑到我想要包含具有相同日期但位置不同的行。我正在使用Postgresql 9.2。

2 个答案:

答案 0 :(得分:1)

将UNION ALL更改为UNION,它应该只返回每个表中的唯一行。

答案 1 :(得分:1)

根据您的描述,查询可能如下所示:
我使用LEFT JOIN / IS NULL从第二个表中排除相同位置和日期的行。 NOT EXISTS将是另一个不错的选择 UNION根本不会按照您的描述进行操作。

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;

使用CREATE TABLE AS代替SELECT INTO 我引用the manual on SELECT INTO

  

CREATE TABLE AS在功能上与SELECT INTO相似。 CREATE TABLE AS   是推荐的语法,因为SELECT INTO的这种形式不是   在ECPG或PL / pgSQL中可用,因为它们解释INTO子句   不同。此外,CREATE TABLE AS提供了一个超集   由SELECT INTO提供的功能。

或者,如果目标表已经存在:

INSERT INTO transactions_combined (<list names of target column here!>)
SELECT ...

我建议不要使用date作为列名。它是每个SQL标准中的reserved word以及PostgreSQL中的函数和数据类型名称。