在 ms-access 中获取 link table 中所有不匹配的条目

Getting all NOT matching entries across a link table in ms-access

我的数据库中有以下关系:

公司有不同的培训,每年重复 2-3 次。

现在我想获取与 tbl_employee 条目无关的所有 tbl_events 条目,并在报告中显示它们。

到目前为止,我已经尝试进行查询,向我提供他们已经访问过的 ev_name 的所有雇员。

qry_visited:

SELECT tbl_employee.em_number
    ,tbl_event.ID AS ev_visited_id
FROM (
    tbl_event INNER JOIN tbl_date ON tbl_event.[ID] = tbl_date.[da_f_event]
    )
INNER JOIN (
    tbl_employee INNER JOIN tbl_training ON tbl_employee.[ID] = tbl_training.[tr_f_employee]
    ) ON tbl_date.[ID] = tbl_training.[tr_f_date];

然后我写了第二个查询: qry_unvisited

SELECT qry_visited.em_number
    ,tbl_event.ev_name
    ,qry_visited.ev_visited_id
FROM qry_visited
RIGHT JOIN tbl_event ON qry_visited.ev_visited_id = tbl_event.ID
WHERE (((qry_visited.ev_visited_id) IS NULL));

如果我将第一个查询限制为只有一名员工,这些查询只能一起使用。我希望所有员工都拥有一个包含 em_number 和 ev_name 的记录集。

我也研究了几天关于使用(和解决)LEFT OUTER、RIGHT OUTER 和 FULL OUTER JOIN 的问题,但是 none 成功了。

感谢您的帮助!

编辑 1

示例: 有 3 个员工(emp1、emp2、epm3)和 3 个事件(ev1、ev2、ev3)

假设

我希望我的结果如下所示:

| employee | not visited events |
  emp1       ev3
  emp2       ev1
  emp3       ev1
  emp3       ev2
  emp3       ev3

这应该会为您提供一个没有相关员工的事件列表。

SELECT DISTINCTROW tbl_event.*
FROM ((tbl_event
LEFT JOIN tbl_date ON tbl_event.ID = tbl_date.da_f_event)
LEFT JOIN tbl_training ON tbl_date.ID = tbl_training.tr_f_date)
LEFT JOIN tbl_employee ON tbl_training.tr_f_employee = tbl_employee.ID
WHERE tbl_employee.ID IS NULL

如果我没理解错的话,你想要的是所有可能的员工事件组合,不包括实际发生的那些。

像这样:

SELECT possibles.*
FROM (
    SELECT tbl_event.ID AS eventID, tbl_employee.ID AS empID
    FROM tbl_event, tbl_employee
) AS possibles
LEFT JOIN (
    SELECT tbl_date.da_f_event AS eventID, tbl_training.tr_f_employee AS empID
    FROM tbl_date
    INNER JOIN tbl_training ON tbl_date.ID = tbl_training.tr_f_date
) AS actuals ON possibles.eventID = actuals.eventID AND possibles.empID = actuals.empID
WHERE actuals.eventID IS NULL

您可以将 tbl_eventtbl_employee 中的更多字段添加到 possibles 子查询。


以下是连接类型的非正式描述:

INNER JOIN

仅包括在联接两侧都匹配的记录;复制多个匹配项的记录

SELECT tbl_event.*, tbl_date.*
FROM tbl_event
INNER JOIN tbl_date ON tbl_event.ID = tbl_date.da_f_event

LEFT JOIN

包括第一个 table 中的所有记录,并且仅包括第二个 table 中匹配的记录。第二个 table 中没有匹配项的行的第二个 table 列的值为 NULL。复制多个匹配项的记录。

SELECT tbl_event.*, tbl_date.*
FROM tbl_event
LEFT JOIN tbl_date ON tbl_event.ID = tbl_date.da_f_event

(还有 RIGHT JOIN,除了颠倒 table 的顺序外,它的作用相同。我还没有找到使用 RIGHT JOIN 的任何充分理由,所以我建议你避免它。)

FULL OUTER JOIN(MS Access 不支持)

包括来自两个 table 的所有记录,即使在连接的另一端没有与给定记录匹配的情况下也是如此。复制多个匹配项的记录。

SELECT tbl_event.*, tbl_date.*
FROM tbl_event
FULL OUTER JOIN tbl_date ON tbl_event.ID = tbl_date.da_f_event

交叉连接,又名笛卡尔积

包括第一个 table 中的每条记录,第二个 table 中的每条记录。

SELECT tbl_event.*, tbl_date.*
FROM tbl_event, tbl_date