我正在努力在搜索查询中表达我想要做的事情,所以如果以前已经回答过,我很抱歉。我希望通过发布一个完整的例子,某人能够指出我正确的方向。我希望找出一个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------+
如果有人可以就编写此查询的最佳方式提供任何建议,或者更好的方法来构建数据库,那将非常有用。
答案 0 :(得分:3)
所以直截了当的答案是:
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;
这将处理您可能缺少经理或地区的情况,但效率会低一些。
希望这些帮助!
答案 1 :(得分:2)
尝试使用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列上都是空的,这对你提供的数据听起来不太合理,甚至是这个结构的想法,那么使用左连接
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