I'm attempting to combine multiple rows into individual rows with multiple columns, where the data is from three tables. I followed the suggestions in MySQL pivot table but the question and answers do not account for multiple joins.
Here are the underlying tables:
table n
+------+----+------+
| name | id | code |
+------+----+------+
| foo | 1 | NULL |
| bar | 2 | z |
| baz | 3 | y |
+------+----+------+
table ac
+------+----+
| code | id |
+------+----+
| h | 1 |
| i | 2 |
+------+----+
table c
+-----+------+-------+
| cid | code | desc |
+-----+------+-------+
| 9 | h | desch |
| 9 | i | desci |
| 8 | z | descz |
| 8 | y | descy |
+-----+------+-------+
Here are the expected results:
+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo | null | desch |
| bar | descz | desci |
| baz | descy | null |
+------+-------+-------+
I can get pretty close to the results I want with:
select
n.name,
n.code as type8,
ac.code as type9
from n
left join ac
on ac.id=n.id
but as expected, this yields the codes only:
+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo | null | h |
| bar | z | i |
| baz | y | null |
+------+-------+-------+
and I'm interested in replacing the codes with the longer descriptions from table c.
The first step is to use case
to return multiple columns of data from multiple rows within the same table using the technique from pivot tables in mysql :
select
n.name,
case when c.cid=8 then c.desc end as type8,
case when c.cid=9 then c.desc end as type9
from n
left join c
on n.code=c.code
This yields the correct results for type8 but nulls for type9:
+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo | null | null |
| bar | descz | null |
| baz | descy | null |
+------+-------+-------+
The next step is to get the results for type9:
select
n.name,
case when c.cid=8 then c.desc end as type8,
case when c.cid=9 then c.desc end as type9
from n
left join ac
on ac.id=n.id
left join c
on c.code=ac.code
This yields:
+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo | null | desch |
| bar | null | desci |
| baz | null | null |
+------+-------+-------+
If these two results are unioned together with
select
n.name,
case when c.cid=8 then c.desc end as type8,
case when c.cid=9 then c.desc end as type9
from n
left join c
on n.code=c.code
union
select
n.name,
case when c.cid=8 then c.desc end as type8,
case when c.cid=9 then c.desc end as type9
from n
left join ac
on ac.id=n.id
left join c
on c.code=ac.code
the rows still need to be combined:
+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| bar | descz | null |
| baz | descy | null |
| foo | null | null |
| foo | null | desch |
| bar | null | desci |
| baz | null | null |
+------+-------+-------+
Finally, I was able to achieve the expected results by using the aggregating technique for removing nulls from a unioned query :
select
n.name,
min(type8), min(type9)
from
(select
n.name,
case when c.cid=8 then c.desc end as type8,
case when c.cid=9 then c.desc end as type9
from n
left join c
on n.code=c.code
union
select
n.name,
case when c.cid=8 then c.desc end as type8,
case when c.cid=9 then c.desc end as type9
from n
left join ac
on ac.id=n.id
left join c
on c.code=ac.code) as n
group by n.name
which yields the results as expected:
+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo | null | desch |
| bar | descz | desci |
| baz | descy | null |
+------+-------+-------+
Another way to get the desired results is to create a pseudo union by combining ifnull(.,.)
with 2 left join
statements and then aggregating the cid
's to mimic a pivot
.
select name
, min(if(cid = 8, `desc`, null)) Type8
, min(if(cid = 9, `desc`, null)) Type9
from (
select cid, code, `desc`, ifnull(name1, name2) name from (
select c.cid, c.code, c.desc, n1.name name1, n2.name name2
from c
left join n n1 on n1.code = c.code
left join ac on ac.code = c.code
left join n n2 on n2.id = ac.id
) q1
) p1
group by name
order by name
;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.