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

mysql-当其中一个表可能缺少连接记录时,如何搜索两个表,mysql,Mysql,我有两张桌子,一张是公司的,一张是联系人的。联系人表包含公司id,该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

我有两张桌子,一张是公司的,一张是联系人的。联系人表包含公司id,该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%' 
我有或没有公司的联系人,但我没有没有没有联系人的公司

事实上,我的问题更糟。因为一个公司可以有很多联系人,所以有一个包含公司id和联系人id的as关联表。
现在我必须从联系人到关联表再到公司,完整的外部联接没有任何区别。

您正在寻找完整的外部联接。这样,您将获得两个表中的所有记录,并在可能的情况下进行连接。不幸的是,MySQL不支持完整的外部联接,所以这里有一个使用联合和左、右外部联接的解决方案

我有三个表,
公司
联系人
,和
公司_联系人
,其中最后一个是关联表。以下是三个项目各自的内容:

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

这正是您要查找的结果。

您要查找的是完整的外部联接。这样,您将获得两个表中的所有记录,并在可能的情况下进行连接。不幸的是,MySQL不支持完整的外部联接,所以这里有一个使用联合和左、右外部联接的解决方案

我有三个表,
公司
联系人
,和
公司_联系人
,其中最后一个是关联表。以下是三个项目各自的内容:

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
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   |
+---------+---------+
这正是您想要的结果。

我建议:

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); 
所以你不会得到完整的空结果。

我建议:

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); 
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%'

因此,您不会得到完整的空结果。

而不是说“左外部联接”,而是说“完全外部联接”。谢谢,我编辑了我的问题,因为我正在浏览一个关联表,并使两个联接都为完全联接,这不会改变问题。对不起,我没有注意到问题被标记为“MySQL”,而不是“SQL”问题。MySQL不支持完整的外部联接,但它们是您所需要的。有很多方法可以模拟它们。我很快会给出答案。请注意:如果问题可以容忍重复行,请使用“union all”而不是“union”,因为这样可以避免消除重复的开销。我无法处理重复行,但数据库没有那么大。我在办公室里发了一封电子邮件,这里的每个人都对你的帮助感到惊讶。谢谢不是说“左外部联接”,而是说“完全外部联接”。谢谢,我编辑了我的问题,因为我正在浏览一个关联表,使两个联接都为完全联接,这不会改变问题。对不起,我没有注意到问题被标记为“MySQL”而不是“SQL”问题。MySQL不支持完整的外部联接,但它们是您所需要的。有很多方法可以模拟它们。我很快会给出答案。请注意:如果问题可以容忍重复行,请使用“union all”而不是“union”,因为这样可以避免消除重复的开销。我无法处理重复行,但数据库没有那么大。我在办公室里发了一封电子邮件,这里的每个人都对你的帮助感到惊讶。谢谢谢谢,我不得不重写这个问题,因为我发现联系人和公司银行之间有一个关联表,我不得不重写这个问题,因为我发现联系人和公司之间有一个关联表。如果没有关联记录,则不会带回公司或联系人。如果没有关联记录,则不会带回公司或联系人
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%'