我需要在MS Access中交叉多个子查询。不幸的是,Access-SQL不支持INTERSECT关键字。我明白,我们如何使用两个表的INNER JOIN来获得我们想要的交集。但是,如何以编程方式创建将构成N个子查询交集的查询?
更具体一点:我有一份员工表和一份专业化表。每个员工都可以拥有多个专业化,这意味着员工和专业化之间存在多对多关系,这些关系由包含员工和专业化ID的附加表所代表,并不复杂。
现在让我们说我想要一份员工清单,所有员工都在某处指定了所有专业。在任何其他SQL引擎中,我只需创建一个子查询列表,并使用INTERSECTION关键字将这些子查询“连接”在一起,创建类似于:
SELECT * FROM (
(SELECT id, first_name, last_name FROM Employees JOIN Emp_spec
ON Employee.id = Emp_spec.spec_id WHERE Emp_spec.spec_id=x_1 )
INTERSECT
...
INTERSECT
(SELECT id, first_name, last_name FROM Employees JOIN Emp_spec
ON Employee.id = Emp_spec.spec_id WHERE Emp_spec.spec_id=x_n )
);
,其中x_1,...,x_n表示与某些特化对应的某些ID。此查询返回一组雇员,所有雇员都具有所有专业x_1,...,x_n。那么如何在没有INTERSECT关键字的Access中创建此类查询。我一直在尝试用INNER JOIN编写等效的查询,但我似乎无法成功。
答案 0 :(得分:6)
也许这就是你的想法。对于测试表[员工] ......
id first_name last_name
-- ---------- ---------
1 Gord Thompson
2 Homer Simpson
3 Hank Kingsley
...和[Emp_spec] ......
emp_id spec_id
------ -------
1 1
1 2
2 1
3 1
3 2
...查询
SELECT * FROM Employees
WHERE id IN (SELECT emp_id FROM Emp_spec WHERE spec_id=1)
AND id IN (SELECT emp_id FROM Emp_spec WHERE spec_id=2)
返回
id first_name last_name
-- ---------- ---------
1 Gord Thompson
3 Hank Kingsley
答案 1 :(得分:0)
如果你想用连接来做,你会为每个规范加入一个子查询,它只从Emp_spec中提取与单个spec_id匹配的行。注意访问多个连接的奇怪的paren要求。
SELECT Employees.id, Employees.first_name
FROM (Employees
INNER JOIN
(SELECT employee_id
FROM Emp_spec
WHERE spec_id = x_1) specx_1
ON Employees.id = specx_1.employee_id)
INNER JOIN
(SELECT employee_id
FROM Emp_spec
WHERE spec_id = x_2) specx_2
ON Employees.id = specx_2.employee_id
...
尽管如此,你可以采取一种捷径,但你可能会认为它过于笨拙。
SELECT Employees.id, Employees.first_name
FROM Employees
INNER JOIN
(SELECT employee_id
FROM Emp_spec
WHERE spec_id IN (x_1, x_2, x_3, ..., x_n)
GROUP BY employee_id
HAVING COUNT(*) = n) match_counts
ON Employees.id = match_counts.spec_id
这里的关键部分是HAVING COUNT(*) = n
。当表格被过滤到您想要的规格时,您只希望让Emp_spec表格中包含n
个记录的员工,以及n
是您所需的规格数量过滤。