问题描述
有关详细信息,请参见this fiddle。
基本上,我正在搜索一个非常基本的测试数据库,以查找BAe,Thales和Google这3家公司之一的工作。
以表格形式显示时,数据库如下所示(该结构的详细信息在小提琴中):
Candidate name Company Job year Skills
One Thales 2015 C
One BAe 2016 Python
One Google 2017 C++
Two BAe 2015 C++
Two Google 2020 Python
Two Thales 2019 C++,UML
Three Google 2019 Python
我正在尝试各种查询,以查找谁在哪些公司工作(技能与该问题无关)。
此查询:
SELECT disTINCT candidate_id FROM jobs j
WHERE 1=1
AND ( EXISTS (
SELECT * FROM companies c
WHERE c.company_id = j.company_id
AND UPPER(c.company_name) LIKE 'THALES'));
正确给出:
+--------------+
| candidate_id |
+--------------+
| 1 |
| 3 |
+--------------+
2 rows in set (0.00 sec)
和此查询:
SELECT disTINCT candidate_id FROM jobs j
WHERE 1=1
AND ( EXISTS (
SELECT * FROM companies c
WHERE c.company_id = j.company_id
AND UPPER(c.company_name) LIKE 'GOOGLE'));
正确给出
+--------------+
| candidate_id |
+--------------+
| 1 |
| 2 |
+--------------+
2 rows in set (0.00 sec)
但是,当我尝试合并时,要找到同时在Thales和Google工作过的候选人,我希望获得候选人1,但结果却空了:
SELECT disTINCT candidate_id FROM jobs j
WHERE 1=1
AND ( EXISTS (
SELECT * FROM companies c
WHERE c.company_id = j.company_id
AND UPPER(c.company_name) LIKE 'THALES')
AND EXISTS (
SELECT * FROM companies c
WHERE c.company_id = j.company_id
AND UPPER(c.company_name) LIKE 'GOOGLE')
);
Empty set (0.00 sec)
上一次查询出了什么问题?
解决方法
您正在搜索jobs
表,因此正在Thales和Google处寻找工作,然后为这些工作选择所有不同的候选人。
由于(您的数据模型中的)一项工作仅在一家公司进行,因此没有工作可以匹配,因此没有候选人被退回。
以下查询将提供您想要的内容:
select * from candidates c
where 1=1
and ( exists (
select * from jobs j
where j.candidate_id = c.candidate_id
and (exists (select * from companies com where com.company_id = j.company_id and upper(com.company_name) like 'THALES'))
))
and ( exists (
select * from jobs j
where j.candidate_id = c.candidate_id
and (exists (select * from companies com where com.company_id = j.company_id and upper(com.company_name) like 'GOOGLE'))
));
,
我想说这是一个聚合查询,它在HAVING
子句中进行了过滤。
select candidate_id
from jobs j
inner join companies c on c.company_id = j.company_id
where c.company_name in ('Thales','Google') -- either one or the other
group by candidate_id
having min(j.company_id) <> max(j.company_id) -- both match
在your db fiddle中,将产生:
| candidate_id | | -----------: | | 1 |