在我们的webapps中,员工可以同时执行一个或多个作业,因此数据库的结构如下:
http://rextester.com/VTFND62465
表tma_employee
:
emp_id | emp_name
-------|---------
1 | BOB
2 | MAX
3 | SALLY
表tma_job
:
job_id | job_name
-------|---------
1 | DEV
2 | SALES
3 | MGMT
员工与工作之间的关系表tma_employee_job
:
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不同,因此可以从上述查询中找到员工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'
);
但是,它需要我使用一个子查询,我想避免使用它,因为主查询是由一个函数构建的,该函数根据它接收的参数从SELECT E.* FROM tma_employee E
开始,然后添加所有各种JOINS和条款。
是否有可能获得与使用子查询的查询相同的结果,同时坚持使用简单的JOINS?
答案 0 :(得分:3)
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;
答案 1 :(得分:1)
试试这个:
SELECT DISTINCT E.*
FROM tma_employee E
LEFT JOIN (
SELECT EJ.emp_id
FROM tma_employee_job EJ
JOIN tma_job J USING (job_id)
WHERE J.job_name = 'DEV'
) T ON E.emp_id = T.emp_id
WHERE T.emp_id IS NULL