在MS-Access中交叉多个子查询(没有INTERSECT关键字)

时间:2014-08-20 17:38:39

标签: sql vba ms-access access-vba ms-jet-ace

我需要在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编写等效的查询,但我似乎无法成功。

2 个答案:

答案 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是您所需的规格数量过滤。