mysql - 当其中一个表可能缺少连接记录时,如何搜索2个表

时间:2011-03-10 23:33:56

标签: mysql

我有2张公司和一张联系表。联系表包含company_id,这是公共字段

我正在撰写搜索,我想从两个表,公司名称和联系人姓名中返回信息。我遇到的问题是,可能有公司没有联系人或没有公司的联系人。两者都是合法的

如果我写

SELECT c.name, k.name from contact c
LEFT OUTER JOIN company k ON k.company_id = c.company id 
WHERE c.name like '%search_word%' || k.name like '%search_word%' 

我收到有或没有公司的联系人,但我没有得到没有联系人的公司。

其实我的问题更糟糕,我意识到。由于公司可以拥有多个联系人,因此包含company_id和contact_id的关联表。 现在我必须从联系人到关联表再到公司,而Full Outer加入没有任何区别。

3 个答案:

答案 0 :(得分:3)

您正在寻找完整的外部联接。这样,您将从两个表中获取所有记录,并尽可能加入。不幸的是,MySQL不支持完全外连接,所以这是一个使用联合和左右外连接的解决方案。

我有三个表,companiescontactscompanies_contacts,其中最后一个是关联表。以下是三者的相应内容:

mysql> select * from companies;

+------------+---------+
| company_id | company |
+------------+---------+
|          1 | Foo     |
|          2 | Bar     |
|          3 | Baz     |
+------------+---------+
3 rows in set (0.00 sec)

mysql> select * from contacts;
+------------+---------+
| contact_id | contact |
+------------+---------+
|          1 | Fred    |
|          2 | Barney  |
|          3 | Wilma   |
|          4 | Betty   |
+------------+---------+
4 rows in set (0.00 sec)

mysql> select * from companies_contacts;
+------------+------------+
| company_id | contact_id |
+------------+------------+
|          1 |          1 |
|          1 |          2 |
|          2 |          2 |
|          2 |          4 |
+------------+------------+
4 rows in set (0.00 sec)

如果您稍微重新考虑,问题会变得更加简单:您希望所有符合条件的联系人以及与之关联的公司(如果可能),并且您希望所有符合条件的公司及其相关联系人尽可能。我们可以使用两个外连接来解决这两个问题:

select    company, contact
from      companies
left join companies_contacts using (company_id)
left join contacts           using (contact_id)
where     company like '%B%';

select     company, contact
from       companies
right join companies_contacts using (company_id)
right join contacts           using (contact_id)
where      contact like '%W%';

在这两个查询之间使用联合将结合它们的结果并消除两者之间的任何重复:

select     company, contact
from       companies
left join  companies_contacts using (company_id)
left join  contacts           using (contact_id)
where      company like '%B%'
union
select     company, contact
from       companies
right join companies_contacts using (company_id)
right join contacts           using (contact_id)
where      contact like '%W%';

在前面提到的数据上,这将给出结果:

+---------+---------+
| company | contact |
+---------+---------+
| Bar     | Barney  |
| Bar     | Betty   |
| Baz     | NULL    |
| NULL    | Wilma   |
+---------+---------+

这正是您正在寻找的结果。

答案 1 :(得分:1)

我建议:

SELECT c.name, k.name from contact c
FULL OUTER JOIN company k ON (k.company_id = c.company id) 
WHERE c.name LIKE '%search_word%' || k.name LIKE '%search_word%'
AND NOT(c.name is null AND k.name is null); 

所以你没有得到完整的空结果。

答案 2 :(得分:1)

select c.name, k.name
from association a
right outer join company k on k.company_id = a.company_id
right outer join contact c on c.company_id = a.company_id
where c.name like '%search_word%' || k.name like '%search_word%'