Reputation: 53
I don't know if the title describes my requirements. I have a table C_Bpartner
(with C_BPartner_ID
as a Primary Key) for employees like this:
name Hiringorderno Orderdate C_Bpartner_ID
A 30 25/02/2002 100
B 47 13/10/2005 101
D 110 22/09/2010 105
and other tables like emp_training:
C_Bpartner_ID TrainingOrderno Orderdate
100 46 14/05/2012
100 58 10/07/2013
101 76 22/10/2015
and emp_penalty:
C_Bpartner_ID PenaltyOrderno Orderdate
105 133 14/05/2012
101 153 25/03/2018
I want the resulting table to be like:
name orderno Orderdate C_Bpartner_ID
A 30 25/02/2012 100
A 46 14/05/2005 100
A 58 10/07/2013 100
B 47 13/10/2005 101
B 76 22/10/2015 101
B 153 25/03/2018 101
D 110 22/09/2010 105
D 133 14/05/2012 105
so, I joined C_BPartner
with itself and coalesce
them, in order to get a second record for the same C_BPartner_ID
. then tried to get the Hiringorderno
from C_BPartner bp
and join C_BPartner pp
with emp_penalty pt
(as an example) and get PenaltyOrderno
and combine them with coalesce(bp.Hiringorderno,pt.PenaltyOrderno)
and do that for all other tables and for Orderdate as well. but it doesn't duplicate records. it picks the first coalesce parameter and discards the other. like this
coalesce(bp.name,pp.name) coalesce(bp.Hiringorderno,pt.PenaltyOrderno) Hiringorderno PenaltyOrderno
A 30 30 null
B 47 47 153
the emp_penalty record for B is not there.
Upvotes: 0
Views: 62
Reputation: 9091
There's other ways to do this, but I think the most clear and intuitive way is to UNION the 3 queries that you're trying to do.
select name, hiringorderno as orderno, orderdate, C_Bpartner_ID, 'HIRING' as ordertype, null as emp_penalty_ID
from C_Bpartner
union all
select bp.name, trainingorderno, t.orderdate, bp.C_Bpartner_ID, 'TRAINING', null
from emp_training t
join C_Bpartner bp
on bp.C_Bpartner_ID = t.C_Bpartner_ID
union all
select bp.name, PenaltyOrderno, p.orderdate, bp.C_Bpartner_ID, 'PENALTY', p.emp_penalty_ID
from emp_penalty p
join C_Bpartner bp
on bp.C_Bpartner_ID = p.C_Bpartner_ID
;
Edit: I added 2 columns to show 2 common ways to differentiate the union'ed records.
One way is to add a constant string or number to each select statement - that way you can use CASE WHEN ordertype = 'PENALTY' ...
or WHERE ordertype = 'TRAINING'
to filter your records.
Another way, like you mentioned, is to fill in a column for one of the selects, like emp_penalty_id, but set it to null
for the other select statements.
All the select statements being unioned together need to have the same number of columns, with compatible types. The first select statement defines the column names and types for the rest, which is why I didn't need to add column aliases to the second and third selects.
Upvotes: 1
Reputation: 142705
One option is to union 3 queries:
SQL> with
2 c_bpartner (name, hiringorderno, orderdate, c_bpartner_id) as
3 (select 'A', 30, date '2002-02-25', 100 from dual union all
4 select 'B', 47, date '2005-10-13', 101 from dual union all
5 select 'D', 110,date '2010-09-22', 105 from dual
6 ),
7 emp_training(c_bpartner_id, trainingorderno, orderdate) as
8 (select 100, 46, date '2012-05-14' from dual union all
9 select 100, 58, date '2013-07-10' from dual union all
10 select 101, 76, date '2015-10-22' from dual
11 ),
12 emp_penalty (c_bpartner_id, penaltyorderno, orderdate) as
13 (select 105, 133, date '2012-05-14' from dual union all
14 select 101, 153, date '2018-03-25' from dual
15 )
16 select c.name, c.hiringorderno as orderno, c.orderdate, c.c_bpartner_id
17 from c_bpartner c
18 union all
19 select c.name, t.trainingorderno, t.orderdate, t.c_bpartner_id
20 from c_bpartner c join emp_training t on t.c_bpartner_id = c.c_bpartner_id
21 union all
22 select c.name, p.penaltyorderno, p.orderdate, p.c_bpartner_id
23 from c_bpartner c join emp_penalty p on p.c_bpartner_id = c.c_bpartner_id
24 order by 1, 2;
N ORDERNO ORDERDATE C_BPARTNER_ID
- ---------- ---------- -------------
A 30 25/02/2002 100
A 46 14/05/2012 100
A 58 10/07/2013 100
B 47 13/10/2005 101
B 76 22/10/2015 101
B 153 25/03/2018 101
D 110 22/09/2010 105
D 133 14/05/2012 105
8 rows selected.
SQL>
Upvotes: 1