在我们的webapps中,员工可以同时执行一个或多个作业,因此数据库的结构如下:
http://rextester.com/VTFND62465
表:
emp_id | emp_name
-------|---------
1 | BOB
2 | MAX
3 | SALLY
表:
job_id | job_name
-------|---------
1 | DEV
2 | SALES
3 | MGMT
员工与工作关系表:
emp_id | job_id
-------|-------
1 | 1
1 | 2
2 | 2
2 | 3
3 | 3
3 | 1
根据这种结构,很容易选择执行一项或多项特定工作的所有员工:
SELECT DISTINCT E.*
FROM tma_employee E
JOIN tma_employee_job EJ USING (emp_id)
JOIN tma_job J USING (job_id)
WHERE J.job_name = 'DEV';
但是,我如何选择所有不执行该工作的员工?
我试着把情况改成这样:
SELECT DISTINCT E.*
FROM tma_employee E
JOIN tma_employee_job EJ USING (emp_id)
JOIN tma_job J USING (job_id)
WHERE J.job_name != 'DEV';
但是,这不起作用,因为例如,BOB也在SALES作业中,这与DEV不同,因此可以从上面的查询中找到employee BOB。
我也发现这是有效的:
SELECT DISTINCT E.*
FROM tma_employee E
WHERE E.emp_id NOT IN (
SELECT EJ.emp_id
FROM tma_employee_job EJ
JOIN tma_job J USING (job_id)
WHERE J.job_name = 'DEV'
);
但是,它要求我使用子查询,我希望避免使用子查询,因为主查询是由一个函数构建的,该函数基于它接收到的参数,从
tma_employee
开始,然后添加所有不同的连接和子句。在坚持简单连接的同时,是否可以获得使用子查询的查询的相同结果?
最佳答案
SQL DEMO不带子查询:
SELECT E.emp_id, E.emp_name
FROM tma_employee E
LEFT JOIN tma_employee_job EJ USING (emp_id)
LEFT JOIN tma_job J ON J.job_id = EJ.job_id
GROUP BY E.emp_id, E.emp_name
HAVING COUNT(CASE WHEN job_name = 'DEV' THEN 1 END) = 0;
关于mysql - 如何选择与联接匹配的记录以外的记录?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40529186/