【问题标题】:Basic boolean logic in a MySQl queryMySQl 查询中的基本布尔逻辑
【发布时间】:2020-12-20 15:50:25
【问题描述】:

详情请见this fiddle

基本上,我正在一个非常基本的测试数据库中搜索以下 3 家公司之一的工作:BAe、Thales 和 Google。

当以表格形式显示时,数据库看起来像这样(结构的完整细节在小提琴中):

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)

最后一个查询有什么问题?

【问题讨论】:

    标签: mysql sql join subquery having-clause


    【解决方案1】:

    我会说这是一个在 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 中,这会产生:

    |候选人ID | | ------------: | | 1 |

    【讨论】:

      【解决方案2】:

      您正在搜索 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'))
      ));
      

      【讨论】:

        猜你喜欢
        • 2011-06-15
        • 1970-01-01
        • 2018-06-15
        • 2014-11-03
        • 2018-01-31
        • 1970-01-01
        • 2020-07-11
        • 1970-01-01
        相关资源
        最近更新 更多