Reputation: 11
I have three tables (simplified version - the whole picture is a bit more complex).
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
I know the table structure isn't the best but that's not what I need help with. The products held in the purchase tables are of different types, if that helps to provide context.
I'm trying to join the tables, using a query like this:
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;
This produces the following:
CustomerID | P1 | P2
--------------------
1 | 51 | 81
1 | 51 | 82
1 | 51 | 83
1 | 52 | 81
1 | 52 | 82
1 | 52 | 83
How do I get it to do this instead?
CustomerID | P1 | P2
-----------|------|---
1 | 51 | null
1 | 52 | null
1 | null | 81
1 | null | 82
1 | null | 83
The first table has a row for every combination of P1 and P2. The second table only has a row for each customer-product combination.
Can I do this without using UNION? The reason I ask, is that because the query will become more complex, using columns from other rows that aren't in PURCHASE1 or PURCHASE2.
If I have to use UNION, how can I do it such that I can still select from other tables and have additional columns in my query?
Upvotes: 1
Views: 267
Reputation: 23588
I would first of all union up all the tables and then join them to the customer table - like so:
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
Upvotes: 1
Reputation: 14858
I would do it this way:
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;
Now you can attach rest of tables without repeated logic.
Upvotes: 1
Reputation: 2097
This uses Union, but in a slightly different way, within subqueries, which might provide you more flexibility.
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)
Upvotes: 0
Reputation: 8517
Use Union . See DEMO. In union, you have to have same number of columns in both queries so use NULL to match number of column in both query
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;
Upvotes: 4
Reputation: 441
It's probably easiest to just change it to a union query like this.
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;
Upvotes: 0