MySQL根据附加表的条件选择行

时间:2017-12-03 07:05:39

标签: php mysql

总而言之,我有几家拥有多个网站和多个部门的公司。每个部门都有一个或多个站点。我正在重复使用所有公司的部门和网站表。我基本上拥有一个全球性的分部和网站,供每家公司使用。我的最终目标是拉动所有属于公司部门的网站。

Company 1  
   |  
   + Division 1  
   |      |  
   |      + Site 1  
   |      + Site 2  
   |
   + Division 2  
   |  
Company 2
   |
   + Division 3  
   |      |  
   |      + Site 3  
   |      + Site 2 
   | 
   + Division 1  
   |

公司

+----+-------------+  
| id |    name     |  
+----+-------------+ 
| 1  |  company 1  |
+----+-------------+
| 2  |  company 2  |
+----+-------------+ 

位点

+----+-------------+  
| id |    name     |  
+----+-------------+ 
| 1  |   site 1    |
+----+-------------+
| 2  |   site 2    |
+----+-------------+
| 3  |   site 3    |
+----+-------------+

+----+-----------------+  
| id |      name       |  
+----+-----------------+ 
| 1  |   division 1    |
+----+-----------------+
| 2  |   division 2    |
+----+-----------------+
| 3  |   division 3    |
+----+-----------------+

company_divisions

+----------+--------------+  
| company  |   division   |  
+----------+--------------+ 
|     1    |       1      |
+----------+--------------+
|     1    |       2      |
+----------+--------------+
|     2    |       1      |
+----------+--------------+
|     2    |       3      |
+----------+--------------+

company_sites

+----------+------------+  
| company  |   site     |  
+----------+------------+ 
|     1    |     1      |
+----------+------------+
|     1    |     2      |
+----------+------------+
|     2    |     2      |
+----------+------------+
|     2    |     3      |
+----------+------------+

我原本以为我可以选择受sitescompany.id约束的所有division.id,但我没有这样的运气。我尝试过子查询:

select * 
from sites 
where id IN (select site from company_sites where company = 3)

并加入:

select s.* 
from sites s 
inner join company_sites cs on s.id = cs.site 
where cs.company = 3

但这些结果仅与company_site有关,而与division无关。我似乎无法弄清楚如何让company_divisions表涉及......这样的事情:

select s.* 
from sites s 
inner join company_sites cs on s.id = cs.site 
inner join company_divisions cd on divisions.id = cd.division 
where cs.company = 2 AND cd.division = 3

如何添加其他条件或查询,以确保用于选择company.id中的site的{​​{1}}与company_sites中的company.id相关company_division 1}}通过division.id

例如,给定company.id = 2division.id = 3我会得到site 2site 3的结果。

总是欢迎建设性的批评。

3 个答案:

答案 0 :(得分:2)

对于这样的树结构,我可能会删除company_divisions和company_sites表并将其设计为这样。

company
+----+-------------+  
| id |    name     |  
+----+-------------+ 
| 1  |  company 1  |
+----+-------------+
| 2  |  company 2  |
+----+-------------+
name should be unique, id is the primary key 

divisions
+----+-----------------+-------------+  
| id |      name       | company id  |
+----+-----------------+-------------+
| 1  |   division 1    |      1      |
+----+-----------------+-------------+
| 2  |   division 2    |      1      |
+----+-----------------+-------------+
| 3  |   division 3    |      2      |
+----+-----------------+-------------+
| 4  |   division 1    |      2      |
+----+-----------------+-------------+
id is the primary key, company id is foreign key referenced to company.id.

sites
+----+-------------+-------------+
| id |    name     | division id |
+----+-------------+-------------+
| 1  |   site 1    |      1      |
+----+-------------+-------------+
| 2  |   site 2    |      1      |
+----+-------------+-------------+
| 3  |   site 3    |      3      |
+----+-------------+-------------+
| 4  |   site 2    |      3      |
+----+-------------+-------------+
id is the primary key, division id  is foreign key referenced to divisions.id.

使用查询

SELECT 
    sites.name as `site`, 
    divisions.name as `division`, 
    company.name as `company` 
FROM sites
LEFT JOIN divisions ON sites.`division id` = divisions.id
LEFT JOIN company ON divisions.`company id` = company.id

会给出

+-------------+------------+-----------+
|    site     |  division  |  company  |
+-------------+------------+-----------+
|   site 1    | division 1 | company 1 |
+-------------+------------+-----------+
|   site 2    | division 1 | company 1 |
+-------------+------------+-----------+
|   site 3    | division 3 | company 2 |
+-------------+------------+-----------+
|   site 2    | division 3 | company 2 |
+-------------+------------+-----------+

从此处开始过滤应该非常简单,只需添加WHERE条件。

答案 1 :(得分:1)

我建议这样,如果你可以修改结构并有单独的分区站点映射表。这也将允许站点属于多个站点的多个站点。

公司表:

+----+-------------+  
| id |    name     |  
+----+-------------+ 
| 1  |  company_1  |
+----+-------------+
| 2  |  company_2  |
+----+-------------+ 

分部表:

+----+-------------+--------------+  
| id |    name     |  company_id  |
+----+-------------+ -------------+
| 1  |  division 1 |      1       |
+----+-------------+--------------+
| 2  |  division 2 |      2       |
+----+-------------+--------------+ 
| 3  |  division 3 |      2       |
+----+-------------+--------------+ 
| 4  |  division 4 |      3       |
+----+-------------+--------------+ 

网站表:

+----+----------------------+
| id |    url               |
+----+----------------------+ 
| 1  |  http:\www.url1.com  |
+----+----------------------+ 
| 2  |  http:\www.url2.com  |
+----+----------------------+
| 3  |  http:\www.url3.com  |
+----+----------------------+
| 4  |  http:\www.url4.com  |
+----+----------------------+

division_site表:

+----+-------------+--------------+  
| id |    div_id   |  site_id     |
+----+-------------+ -------------+
| 1  |       1     |      1       |
+----+-------------+--------------+
| 2  |       1     |      2       |
+----+-------------+--------------+
| 3  |       2     |      1       |
+----+-------------+--------------+
| 4  |       2     |      3       |
+----+-------------+--------------+
| 5  |       2     |      4       |
+----+-------------+--------------+
| 6  |       3     |      1       |
+----+-------------+--------------+
| 7  |       4     |      2       |
+----+-------------+--------------+

所以你可以拥有类似的东西:

select company.name as company_name ,division.name as division_name ,GROUP_CONCAT(sites.url) as "Site URL's" from company inner join division on division.company_id = company.id left JOIN div_sites on div_sites.div_id = division.id inner join sites on sites.id = div_sites.site_id where company.id = 1 and division.id =1 GROUP by division.id

哪会返回

+----+-------------+-------------------+-----------------------+  
| company name     |    division name  |    Url's              |
+----+-------------+-------------------+------------------------
|   company_1      |    div 1          | http:\www.url1.com,   |
|                  |                   | http:\www.url2.co     |
+------------------+-------------------+-----------------------+  

答案 2 :(得分:0)

您提供的类似代码,检查company_site.company = 3,这是一个在您的表中不存在的值。与company_divisions表类似。事实上,没有公司3.尝试存在的数据