mysql - 如何在mysql中通过多个表的多个连接来组合多行

标签 mysql

我正在尝试将多行合并为具有多列的单独行,其中数据来自三个表。我遵循了MySQL pivot table中的建议但问题和答案不考虑多重连接。

以下是基础表格:

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 |
+-----+------+-------+

以下是预期结果:

+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo  | null  | desch |
| bar  | descz | desci |
| baz  | descy | null  |
+------+-------+-------+

我可以通过以下方式获得非常接近我想要的结果:

select 
n.name,
n.code as type8,
ac.code as type9
from n
left join ac
on ac.id=n.id

但正如预期的那样,这仅产生代码:

+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo  | null  | h     |
| bar  | z     | i     |
| baz  | y     | null  |
+------+-------+-------+

我有兴趣用表 c 中的较长描述替换代码。

最佳答案

第一步是使用 case 使用 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 

这会为 type8 产生正确的结果,但为 type9 产生空值:

+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo  | null  | null  |
| bar  | descz | null  |
| baz  | descy | null  |
+------+-------+-------+

下一步是获取 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

这会产生:

+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo  | null  | desch |
| bar  | null  | desci |
| baz  | null  | null  |
+------+-------+-------+

如果这两个结果用 联合在一起

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

行仍然需要合并:

+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| bar  | descz | null  |
| baz  | descy | null  |
| foo  | null  | null  |
| foo  | null  | desch |
| bar  | null  | desci |
| baz  | null  | null  |
+------+-------+-------+

最后,我通过使用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

产生预期结果:

+------+-------+-------+
| name | type8 | type9 |
+------+-------+-------+
| foo  | null  | desch |
| bar  | descz | desci |
| baz  | descy | null  |
+------+-------+-------+

关于mysql - 如何在mysql中通过多个表的多个连接来组合多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56403019/

相关文章:

php : speed up levensthein comparing, 10k + 记录

MySql 对小数列进行加法和除法

MySQL 无法使用 '2014-10-19 00:00:00' 更新 TIMESTAMP 字段

php - Yii的Ar模型中Mysql "on Duplicate Key Update"的等效方法是什么

php - 使用 php 和 mysql 将图像更新到数据库中

MySQL查询以在两列中显示重复项

android - SQLite 数据库大于 CSV 平面文件?

java - 我想从 mysql 在此 ListView 中添加两个项目

没有任何 JOIN 谓词的 MySQL JOIN

php - 从 MySQL Google Maps v3 上的表中删除标记