SQL连接 - 重复行

时间:2015-07-17 13:41:43

标签: sql oracle tsql oracle11g oracle10g

我有三张桌子(简化版 - 整个图片有点复杂)。

TABLE: CUSTOMER    TABLE: PURCHASE1           TABLE: PURCHASE2
===============    =======================    =======================
CustomerID         CustomerID  | ProductID    CustomerID  | ProductID
---------------    ------------|----------    ------------|----------
1                  1           | 51            1          | 81
2                  1           | 52            1          | 82
3                  2           | 52            1          | 83

我知道桌面结构不是最好的,但这不是我需要帮助的。购买表中的产品属于不同类型,如果这有助于提供背景信息。

我正在尝试使用如下查询加入表:

Select 
    customer.customerid, purchase1.productid as P1, 
    purchase2.productid as P2
From  
    customer
Left join 
    purchase1 on customer.customerid = purchase1.customerid
Left join 
    purchase2 on customer.customerid = purchase2.customerid
Where 
    customer.customerid = 1;

这会产生以下结果:

CustomerID | P1 | P2
--------------------
1          | 51 | 81
1          | 51 | 82
1          | 51 | 83
1          | 52 | 81
1          | 52 | 82
1          | 52 | 83

我如何才能做到这一点?

CustomerID | P1   | P2
-----------|------|---
1          | 51   | null
1          | 52   | null
1          | null | 81
1          | null | 82
1          | null | 83

对于P1和P2的每个组合,第一个表都有一行。第二个表只对每个客户 - 产品组合有一行。

我可以不使用UNION吗?我问的原因是,因为查询将变得更复杂,使用不在PURCHASE1或PURCHASE2中的其他行的列。

如果我必须使用UNION,我怎么能这样做,以便我仍然可以从其他表中选择并在我的查询中添加其他列?

5 个答案:

答案 0 :(得分:4)

使用Union。 See DEMO。在联合中,您必须在两个查询中具有相同数量的列,因此使用NULL来匹配两个查询中的列数

Select * from (Select customer.customerid, purchase1.productid as P1, NULL as P2
from customer
INNER join purchase1
on customer.customerid = purchase1.customerid

UNION ALL

Select customer.customerid, NULL as P1, purchase2.productid as P2
from customer 
INNER join purchase2
on customer.customerid = purchase2.customerid) tb
where tb.customerid = 1;

答案 1 :(得分:1)

我会这样做:

select customerid, p1, p2
  from customer
  left join (
    select customerid, productid p1, null p2 from purchase1
    union all
    select customerid, null p1, productid p2 from purchase2
    ) using (customerid)
  where customerid = 1;

SQLFiddle demo

现在您可以附加其余表而无需重复逻辑。

答案 2 :(得分:1)

我首先将所有表联合起来,然后将它们加入到客户表中 - 就像这样:

with customer as (select 1 customerid, 'bob' name from dual union all
                  select 2 customerid, 'ted' name from dual union all
                  select 3 customerid, 'joe' name from dual),
    purchase1 as (select 1 customerid, 51 productid from dual union all
                  select 1 customerid, 52 productid from dual union all
                  select 2 customerid, 52 productid from dual),
    purchase2 as (select 1 customerid, 81 productid from dual union all
                  select 1 customerid, 82 productid from dual union all
                  select 1 customerid, 83 productid from dual),
    -- end of mimicking your table and data; main query is below:
    purchases as (select customerid, productid productid1, null productid2
                  from   purchase1
                  union all
                  select customerid, null productid1, productid productid2
                  from   purchase2)
select c.customerid,
       c.name,
       p.productid1,
       p.productid2
from   customer c
       inner join purchases p on (c.customerid = p.customerid)
order by c.customerid,
         p.productid1,
         p.productid2;

CUSTOMERID NAME PRODUCTID1 PRODUCTID2
---------- ---- ---------- ----------
         1 bob          51           
         1 bob          52           
         1 bob                     81
         1 bob                     82
         1 bob                     83
         2 ted          52           

答案 3 :(得分:0)

将它更改为这样的联合查询可能最容易。

select customer.customerid, purchase1.productid as P1, null as P2
from customer
left join purchase1
on customer.customerid = purchase1.customerid
union all
select customer.customerid, null as P1, purchase2.productid as P2
from customer
left join purchase2
on customer.customerid = purchase2.customerid
where customer.customerid = 1;

答案 4 :(得分:0)

这使用了Union,但在子查询中使用的方式稍有不同,这可能会为您提供更大的灵活性。

select distinct t1.pID,t2.pID
from (select ID,pID from Puchase1
        union all
        select ID, null from Purchase1) t1
right join (select ID,pID from Purchase2
            union all
            select ID, null from Purchase2) t2
on t1.ID = t2.ID
where t1.ID = 1
and (t1.pID is not null or t2.pID is not null)
and (t1.pID is null or t2.pID is null)
相关问题