我来这里寻求复杂查询的帮助。我为此尝试了很多不同的东西,并没有得到我想要的结果。我的模式的淡化版本如下:有问题的三个表是Employees表,EmployeeTraining表和RequiredTraining表。 employees表包含员工的信息,例如empID,姓名,地址,电子邮件,positionWorked等.EmployeeTraining表包含empID和TrainingName。RequiredTraining表有一个Position和TrainingName。
员工: empID , 名称, 位置
EmployeeTraining: empID , 的 trainingName
requiredTraining:职位, 的 trainingName
以下是一些示例数据,只是为了进一步澄清:
员工
*EMPID~~Name~~Position~~
1 Ted Accountant
2 Bob Janitor
employeeTraining
**empID~~TrainingName**
1 Crunching Numbers
1 Microsoft Excel
1 Using an Abicus
2 Lemon Pledge 100
2 Scrubbing Toilets
requiredTraining
**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 JOE EmployeeTraining on employees.empid = employeetraining.empID WHERE empID = me.empID)
我还想要另一个子表单,其中显示员工尚未完成的培训,这是当前职位所必需的。这是我在努力的地方。我对使用MS Access的查询构建器不熟悉或不熟悉,但我尝试过“查找无法匹配的”查询以及尝试编写自己的查询。这似乎是MINUS操作可行,但MS Access不支持MINUS。我已尝试使用null谓词的LEFT JOIN以及上述查询中的NOT IN到requiredTraining表的查询,但我没有得到我正在寻找的结果。
例如,我正在尝试为此示例数据编写的查询结果为:
代表employeeID 1(特别是会计师)
需要“TPS报告”培训
员工2(Bob the Janitor)
鲍勃已经完成了他所有的职位培训。我正在尝试的尝试查询的示例是:
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)))
编辑:此问题已得到解答。谢谢大家的帮助。您的查询虽然各不相同,但都完成了目标。
答案 0 :(得分: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”子句使用相关子查询来查找员工尚未完成的子查询。
答案 1 :(得分: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
请注意,如上所述,您实际上不需要加入employees表...您可以使用以下内容:
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
答案 2 :(得分:1)
下面的查询是从两个带有SQL剪切的MS Access查询创建的,并粘贴到派生表中。这两个查询选择具有当前培训的员工(#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 );
答案 3 :(得分: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;