繁体   English   中英

通过一个其他表将一个表连接到另一个表

[英]Joining one table through other tables to another

我正在努力在搜索查询中阐明我要尝试执行的操作,因此,如果以前已经回答过此问题,我们感到抱歉。 我希望通过发布一个完整的示例,有人可以为我指出正确的方向。 我正在寻找一个mySQL查询,或者学习一种更好的结构数据库的方法,以实现以下目的。

如果我有4个表,通过一个表链接到另一个表的最佳方法是什么。 在下面,我有一个site_table,其中包含经理(站点的总经理),区域和国家的ID。 region_table和country_table也指向manager_table。 site_table上的manager_id也指向manager_table。 这些表可能如下所示:

site_table
+------------+------------+-----------+------------+
|    name    | manager_id | region_id | country_id |
+------------+------------+-----------+------------+
| Manchester |          1 |         1 |          1 |
| Essex      |          2 |         2 |          1 |
| Perth      |          3 |         3 |          2 |
| Birmingham |          4 |         1 |          1 |
+------------+------------+-----------+------------+

region_table
+-----------+---------+------------+
| region_id |  name   | manager_id |
+-----------+---------+------------+
|         1 | Central |          5 |
|         2 | South   |          6 |
|         3 | North   |          7 |
+-----------+---------+------------+

country_table
+------------+----------+------------+
| country_id |   name   | manager_id |
+------------+----------+------------+
|          1 | England  |          9 |
|          2 | Scotland |          8 |
+------------+----------+------------+

manager_table
+------------+-----------------+
| manager_id |      name       |
+------------+-----------------+
|          1 | Joe Bloggs      |
|          2 | Graham Smith    |
|          3 | Pat Sharp       |
|          4 | Sally May       |
|          5 | Peter Barratt   |
|          6 | Jimmy Stone     |
|          7 | Kim Keller      |
|          8 | Peter Sheet     |
|          9 | Matthew Lampart |
+------------+-----------------+

我想查询数据库以返回站点名称,总经理(GM)名称,区域经理(RM)名称和国家经理(CM)名称,如下所示:

+------------+--------------+---------------+-----------------+
| site_name  |   GM_name    |    RM_name    |     CM_name     |
+------------+--------------+---------------+-----------------+
| Manchester | Joe Bloggs   | Peter Barratt | Matthew Lampart |
| Essex      | Graham Smith | Jimmy Stone   | Matthew Lampart |
| Perth      | Pat Sharp    | Kim Keller    | Peter Sheet     |
| Birmingham | Sally May    | Peter Barratt | Matthew Lampart |
+------------+--------------+---------------+-----------------+

我想这样做,我必须将site_table链接到region_table和country_table,然后再将manager_table链接到site_table,region_table和country_table,但是我想尽办法将自己束缚。 我看到的链接看起来像这样:

site_table---+-----------------------+
             |                       |
             +-----region_table----manager_table
             |                       |
             +----country_table------+

如果有人可以提供有关编写此查询的最佳方法或构建数据库的更好方法的任何建议,那将非常有帮助。

因此,简单的答案是:

select
  s.name site_name,
  gm.name GM_name,
  rm.name RM_name,
  cm.name CM_name
from
  site_table s
  inner join manager_table gm on gm.manager_id = s.manager_id
  inner join region_table r on r.region_id = s.region_id
  inner join manager_table rm on rm.manager_id = r.manager_id
  inner join country_table c on c.country_id = s.country_id
  inner join manager_table cm on cm.manager_id = c.manager_id;

但这仅在每个GM,RM和CM始终至少有一个区域和经理的情况下才有效。 可能更灵活一些:

select
  s.name site_name,
  gm.name GM_name,
  rm.name RM_name,
  cm.name CM_name
from
  site_table s
  left outer join manager_table gm on gm.manager_id = s.manager_id
  left outer join region_table r on r.region_id = s.region_id
  left outer join manager_table rm on rm.manager_id = r.manager_id
  left outer join country_table c on c.country_id = s.country_id
  left outer join manager_table cm on cm.manager_id = c.manager_id;

这样可以处理您可能缺少经理或地区但效率稍低的情况。

希望这些帮助!

尝试使用CASE EXPRESSION使用条件聚合。 您的想法是正确的,您需要先连接所有三个表,然后才能看到我已连接到m.manager_id IN(s.manager_id,r.manager_id,c.manager_id)上的经理表。 之后的聚合将使输出旋转,因为每个名称将有3条记录,其中每个表都包含manager_name。

SELECT s.name,
      MAX(CASE WHEN s.manager_id = m.manager_id THEN m.name END) as GM_NAME,
      MAX(CASE WHEN r.manager_id= m.manager_id THEN m.name END) as RM_NAME,
      MAX(CASE WHEN c.manager_id = m.manager_id THEN m.name END) as CM_NAME
FROM site_table s
INNER JOIN region_table r ON(s.region_id = r.region_id)
INNER JOIN country_table c ON(s.country_id = c.country_id)
INNER JOIN manager_table m ON(m.manager_id IN(s.manager_id,r.manager_id,c.manager_id))
GROUP BY s.name

如果您可能缺少数据-任何site_table id列都为null,这对您提供的数据甚至是这种结构的想法都不太合理,那么请使用左连接

SELECT s.name,
      MAX(CASE WHEN s.manager_id = m.manager_id THEN m.name END) as GM_NAME,
      MAX(CASE WHEN r.manager_id= m.manager_id THEN m.name END) as RM_NAME,
      MAX(CASE WHEN c.manager_id = m.manager_id THEN m.name END) as CM_NAME
FROM site_table s
LEFT JOIN region_table r ON(s.region_id = r.region_id)
LEFT JOIN country_table c ON(s.country_id = c.country_id)
LEFT JOIN manager_table m ON(m.manager_id IN(s.manager_id,r.manager_id,c.manager_id))
GROUP BY s.name

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM