如何选择外表中没有匹配的记录(左外连接)

时间:2012-01-12 13:35:22

标签: sql oracle11g

我有一张表可以保存我的资源:

资源|的ressource-ID

一个包含关联的表

Ressource-ID |雇员-ID

如何选择可用的员工资源,即不在关联表中?

我试过这个,但它不起作用:

select r.ress, r.ress_id
FROM Ressource r
LEFT outer JOIN Ressource_Employee_Association a ON r.ress_id = a.ress_id
WHERE a.emp_id = 'ID00163efea66b' and a.ress_id IS NULL

有什么想法吗?

由于 托马斯

4 个答案:

答案 0 :(得分:1)

在LEFT JOIN之后应用WHERE子句。这意味着您当前正在尝试获取Ressource_Employee_Association中没有匹配记录的结果,但emp_id等于'ID00163efea66b'

但如果没有匹配的记录,emp_idNULL以外的其他内容怎么办?

一种选择是将WHERE子句的一部分移动到连接...

SELECT
  r.ress, r.ress_id
FROM
  Ressource r
LEFT OUTER JOIN
  Ressource_Employee_Association a
    ON r.ress_id = a.ress_id
    AND a.emp_id = 'ID00163efea66b'
WHERE
  a.ress_id IS NULL

这将列出与员工'ID00163efea66b'无关的所有资源。

修改

您的评论暗示您想要的是......
- 列出所有员工的视图
- 对于每个员工列表,他们没有的每个资源

这需要一个列出所有员工的额外表格。

SELECT
  *
FROM
  Employee
CROSS JOIN
  Ressource
WHERE
  NOT EXISTS (SELECT * FROM Ressource_Employee_Association
               WHERE emp_id  = Employee.id
                 AND ress_id = Ressource.id)

答案 1 :(得分:1)

这有用吗?

select r.ress, r.ress_id
from resource r
where not exists 
(
    select 1 from ressource_emplyee_association a 
    where a.emp_id = '...' and a.ress_id = r.ress_id
)

修改
在此之前,我有以下内容,但根据以下评论进行了更改:

select r.ress, r.ress_id
from resource r
where not exists 
(
    select top 1 1 from ressource_emplyee_association a 
    where a.emp_id = '...' and a.ress_id = r.ress_id
)

答案 2 :(得分:1)

SELECT * 
  FROM Ressource
 WHERE ress_id IN (
                   SELECT ress_id, 
                     FROM Ressource 
                   MINUS
                   SELECT ress_id
                     FROM Ressource_Employee_Association 
                    WHERE emp_id = 'ID00163efea66b'
                  );

答案 3 :(得分:1)

在写完我的上述评论后,看一下建议的解决方案:我想我对你要做的事情有了更多的了解。

假设您的资源表中有无限数量的资源,您希望为每个员工选择未分配的资源(基于资源关联表中任何特定员工的不存在)。

为了实现这一目标(并获得全面的员工清单),您需要第3个表格,以便参考完整的员工列表。您还需要CROSS JOIN将所有资源放入员工列表中(假设每个员工都可以访问每个资源),然后您LEFT JOINLEFT OUTER JOIN无论如何)将您的关联列表放到resource_idemployee_idresource_id表中的resources以及employee_id表中的employees相匹配的查询。然后,添加where子句,过滤掉将员工分配给资源的所有记录。这将为您提供员工可用的资源,这些资源也未注销。这是令人费解的,所以希望这个问题能够带来更多的亮点:

SELECT e.employee_id, e.employee, r.res_id, r.res

FROM employees e
CROSS JOIN resources r
LEFT JOIN assigned_resources ar
    ON ar.employee_id = e.employee_id AND r.res_id = ar.res_id

WHERE ar.res_id IS NULL

如果您没有employees表,则可以使用分配的资源表完成相同的操作,但您将仅限于选择已分配资源的员工。您需要添加GROUP BY查询,因为关联表中可能存在多个员工定义。这是查询的样子:

SELECT e.employee_id, r.res_id, r.res

FROM assigned_resources e
CROSS JOIN resources r
LEFT JOIN assigned_resources ar
    ON ar.employee_id = e.employee_id AND r.res_id = ar.res_id

WHERE ar.res_id IS NULL

GROUP BY e.employee_id, r.res_id