Prep the sample data:
create table a (
id number,
name varchar2(10)
)
/
create table b (
id number,
val_name varchar2(10)
)
/
create table c (
id number,
a_id number,
b_id number,
val number
)
/
insert into a values ( 1, 'FOO' );
insert into a values ( 2, 'BAR' );
insert into a values ( 3, 'BAZ' );
insert into a values ( 4, 'QUX' );
insert into b values ( 1, 'GOOS' );
insert into b values ( 2, 'BLOBS' );
insert into c values ( 1, 1, 1, 6 );
insert into c values ( 2, 1, 2, 7 );
insert into c values ( 3, 2, 1, 8 );
insert into c values ( 4, 3, 2, 9 );
commit;
Try this query:
select distinct a.name,
first_value(case when b_goo.val_name is not null then c.val else null end) over (partition by a.name order by b_goo.val_name nulls last ) goos,
first_value(case when b_blob.val_name is not null then c.val else null end) over (partition by a.name order by b_blob.val_name nulls last ) blobs
from a
left outer join c
on c.a_id = a.id
left outer join b b_goo
on b_goo.id = c.b_id
and b_goo.val_name = 'GOOS'
left outer join b b_blob
on b_blob.id = c.b_id
and b_blob.val_name = 'BLOBS'
/
Results:
NAME GOOS BLOBS
---------- ---------- ----------
QUX
BAR 8
FOO 6 7
BAZ 9
[edit] sorry, you wanted to show the ids, not the names, fixed that here[/edit]
So I just do some outer joins first, using 2 "copies" of your table B .. so I can have a GOO in 1 column and BLOBs in another.
Then I use FIRST_VALUE analytic function to pick out the first non-null value which helps collapse the duplicate rows ..
DISTINCT helps with that as well.
I did this in Oracle, however, it should work as is in other RDBMS.