1

我来这里是为了帮助处理一个复杂的查询。为此,我尝试了很多不同的方法,但并没有得到我想要的结果。我的架构的淡化版本如下:有问题的三个表是Employees 表、EmployeeTraining 表和RequiredTraining 表。employees 表保存员工的信息,例如empID、姓名、地址、电子邮件、positionWorked 等。EmployeeTraining 表保存empID 和TrainingName。RequiredTraining 表保存Position 和TrainingName。

员工:empID、姓名、职位

EmployeeTraining:empIDtrainingName

requiredTraining: 职位培训名称

这是一些示例数据,只是为了进一步澄清:

雇员

              *EMPID~~Name~~Position~~
                  1      Ted     Accountant

                  2      Bob     Janitor

员工培训

                 **empID~~TrainingName**
                    1          Crunching Numbers

                    1          Microsoft Excel

                    1          Using an Abicus

                    2          Lemon Pledge 100

                    2          Scrubbing Toilets

需要培训

                  **position**~~**TrainingName**


                    Accountant    Crunching Numbers

                    Accountant    Microsoft Excel

                    Accountant    Using an Abicus

                    Accountant    TPS Reports

                    Janitor       Lemon Pledge 100

                    Janitor       Scrubbing Toilets

用英语,从长远来看,我想从表单中选择一个员工,并有一个子表单显示从该员工完成的所有培训(SELECT * FROM Employees INNER JOIn EmployeeTraining on employees.empid = employeetraining.empID WHERE empID =我.empID)

我还想要另一个子表单来显示员工尚未完成的当前职位所需的培训。这就是我挣扎的地方。我不熟悉或不习惯使用 MS Access 的查询生成器,但我尝试过“查找不匹配”查询以及尝试编写自己的查询。这似乎可以使用 MINUS 操作,但 MS Access 不支持 MINUS。我已经尝试了一个带有空谓词的 LEFT JOIN 以及从上述查询到 requiredTraining 表的查询的 NOT IN,但我没有得到我正在寻找的结果。

例如,我尝试为此示例数据编写的查询结果将是:

对于employeeID 1(Ted the Accountant)

ted需要“TPS报告”培训

员工 2(清洁工鲍勃)

Bob 已经完成了针对他的职位的所有培训。

我正在尝试的一个尝试查询的示例是:

      SELECT employees.position,employeeTraining.empid,employeetraining.TrainingName          
      FROM EmployeeTraining 
      InNER JOIN Employees ON EmployeeTraining.empid = employees.empid
      WHERE empid = '1'
      LEFT JOIN
      SELECT TrainingName,Position FROM requiredTraining
      ON EmployeeTraining.Training = RequiredTraining.Training
      WHERE (((EmployeeTraining.Training is Null)))

编辑:这个问题已经回答了。感谢大家的帮助。您的查询,虽然每个都不同,但都实现了目标。

4

4 回答 4

1

实际上,您与其他查询非常接近……您可以尝试使用 NOT IN 子句。例如,正如您所说,您可以获得所有完成特定培训的员工,如下所示:

SELECT e.empID, e.name, e.Position, et.TrainingName
FROM Employees e
JOIN EmployeeTraining et ON e.empID = et.empID
WHERE empID = me.empID

您现在想要的是所有尚未完成培训的员工......您可以在 trainingName 表上进行连接,确保培训类型不在您已经创建的查询中,如下所示:

SELECT e.empID, e.name, e.Position, rt.TrainingName
FROM Employees e
JOIN requiredTraining rt ON e.Position = rt.Position
WHERE rt.TrainingName NOT IN
(
   SELECT et.TrainingName
   FROM Employees e
   JOIN EmployeeTraining et ON e.empID = et.empID
   WHERE empID = me.empID
)
  AND e.empID = me.empID

请注意,如上所述,您实际上不需要加入员工表......您可以使用以下内容:

SELECT e.empID, e.name, e.Position, rt.TrainingName
FROM Employees e
JOIN requiredTraining rt ON e.Position = rt.Position
WHERE rt.TrainingName NOT IN
(
   SELECT et.TrainingName
   FROM EmployeeTraining
   WHERE et.empID = me.empID
)
  AND e.empID = me.empID
于 2012-06-19T14:09:04.030 回答
1

以下查询应返回具有他们需要完成的培训名称的所有员工:

select e.emp_id, rt.TrainingName
from employees e left outer join
     RequiredTraining rt
     on e.position = rt.position
where rt.TrainingName not in (select TrainingName from EmployeeTraining et where et.empId = e.EmpId)

“from”子句中的连接查找所有必需的培训。“where”子句然后使用相关子查询来查找员工尚未完成的子查询。

于 2012-06-19T13:51:56.060 回答
1

下面的查询是从两个 MS Access 查询创建的,其中 SQL 剪切并粘贴到派生表中。这两个查询选择接受当前培训的员工 (#1) 和接受所需培训的员工 (#2)。它不可更新,但易于创建。您可以通过在末尾添加一行来仅显示缺少的训练:

WHERE et.TrainingName Is Null

要选择单个员工,您可以添加一行:

WHERE rt.EMPID=1 AND et.TrainingName Is Null

但是,您提到了一个子表单,因此我希望您希望使用链接子字段和主字段来限制员工。

SQL

SELECT rt.empid,
       rt.position,
       rt.trainingname,
       et.trainingname AS IsTrained
FROM   (SELECT employees.empid,
               requiredtraining.position,
               requiredtraining.trainingname
        FROM   employees
               INNER JOIN requiredtraining
                       ON employees.position = requiredtraining.position) AS rt
       LEFT JOIN (SELECT employees.empid,
                         employees.position,
                         employeetraining.trainingname
                  FROM   employees
                         INNER JOIN employeetraining
                                 ON employees.empid = employeetraining.empid) AS
                 et
              ON ( rt.trainingname = et.trainingname )
                 AND ( rt.position = et.position )
                 AND ( rt.empid = et.empid ); 
于 2012-06-19T14:35:05.280 回答
1

以下查询根据使用 Access 2007 测试的示例数据返回此结果集。

EMPID Position    TrainingName
1     Accountant  TPS Reports

SELECT
    sub.EMPID,
    sub.Position,
    sub.TrainingName
FROM
    (
        SELECT
            e.EMPID,
            e.Position,
            rt.TrainingName
        FROM
            Employees AS e
            INNER JOIN RequiredTraining AS rt
            ON e.Position = rt.position
    ) AS sub
    LEFT JOIN EmployeeTraining AS et
    ON
            sub.TrainingName = et.TrainingName
        AND sub.EMPID = et.empID
WHERE et.TrainingName Is Null;
于 2012-06-19T15:03:03.730 回答