我有一个高级查询/报告,我需要在Access 2007中创建帮助。 我需要生成的查询是:
Employee Last, Employee First, Employee Role, Course Name, StartDate, EndDate, Attended
我需要处理的逻辑是:
一些额外的逻辑可能是添加:Trainer Last to the Select
逻辑:如果Data isNull,Trainer Last = No Trainer Assigned
它不会让我发布数据库的图片。所以这里是带有参考完整性的表:
Tables: Fields
Employee: Employee_PK, Employee_Last, Employee_first, Employee_userid
Role: Role_PK, RoleNAme
EmployeeRole: EmployeeRole_PK, Employee_ID, Role_ID
Location: Location_PK, Location
Course: Course_PK, StartDate, EndDate, CourseName, CourseNotes, Location_ID
CourseAttendance: CourseAttendance_PK, Course_ID, Employee_ID
CourseRole: CourseRole_PK, Course_ID, Role_ID
Trainer: Trainer_PK, TrainerLast, TrainerFirst
TrainerCourse:Trainer_PK, Trainer_ID, Course_ID
所以你可以看到它已经标准化,并且需要多个多对多的表 PK用于主键,ID用作外键。所以是的,这些都没关系。
编辑:
此查询已发布在评论中:
我尝试了很多问题。
SELECT qryEmployeeCoursesForRole.*, IIf(IsNull([courseattendance_PK]),"No","Yes") AS Attended
FROM qryEmployeeCoursesForRole
LEFT JOIN CourseAttendance
ON (qryEmployeeCoursesForRole.COURSE_ID = CourseAttendance.COURSE_ID)
AND (qryEmployeeCoursesForRole.EMPLOYEE_ID = CourseAttendance.EMPLOYEE_ID);
这个没有处理No course defined的例外 -
Course Table:
COURSE_PK START DATE END DATE COURSENAME NOTES LOCATION_ID
1 12/2/2012 12/2/2012 OTC No Notes 3
2 12/1/2012 12/1/2012 OTC No Note 2
3 1/5/2012 1/5/2012 Requistions Text Text Text 1
and P-Cards
CourseAttendance Table:
COURSEATTENDANCE_PK COURSE_ID EMPLOYEE_ID
1 1 1
2 2 2
CourseRole Table:
COURSEROLE_PK COURSE_ID ROLE_ID
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
Employee Table:
EMPLOYEE_PK EMPLOYEE_LAST EMPLOYEE_FIRST EMPLOYEE_USERID
1 Ables Christopher LG854
2 Ables Gary LC876
3 Ables Steven LQ875
EmployeeRole Table:
EMPLOYEEROLE_PK EMPLOYEE_ID ROLE_ID
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 3 4
Location Table:
LOCATION_PK LOCATION
1 New York
2 New Brunfels
3 Ontario
4 China
Role Table:
ROLE_PK ROLENAME
1 Service Coordinator
2 Service Planner
3 Service Entry
4 AP Invoice
Trainer Table:
TRAINER_PK TRAINER_LAST TRAINER_FIRST TRAINER_USERID
1 Brunet Janell
2 Gibson Jim hb476
3 Taylor Diana hblo7hg
TrainerCourse Table:
TRAINERCOURSE_PK TRAINER_ID COURSE_ID
1 1 1
2 1 2
3 2 2
现在我已经详细介绍了这个逻辑,看来这不仅需要花哨的查询。如果你需要我更具体,我可以,但它需要我上传文件或其他东西。
我创建的所有查询和查询原因:
EmployeeCourseOutsideofRole
SELECT CourseAttendance.EMPLOYEE_ID, CourseAttendance.COURSE_ID, Course.COURSE_NAME
FROM Course INNER JOIN (CourseAttendance LEFT JOIN qryEmployeeCoursesForRole ON
(CourseAttendance.COURSE_ID = qryEmployeeCoursesForRole.COURSE_ID) AND
(CourseAttendance.EMPLOYEE_ID = qryEmployeeCoursesForRole.EMPLOYEE_ID)) ON Course.COURSE_PK =
CourseAttendance.COURSE_ID
WHERE (((qryEmployeeCoursesForRole.EMPLOYEE_ID) Is Null) AND
((qryEmployeeCoursesForRole.COURSE_ID)
Is Null));
If Employee took a Course and the CourseRole not equal to EmployeeRole
EmployeeCoursesForRoleSub:
SELECT [Employee_last] & " " & [employee_first] AS FullName, Role.ROLENAME,
EmployeeRole.EMPLOYEE_ID, EmployeeRole.ROLE_ID
FROM Role INNER JOIN (Employee INNER JOIN EmployeeRole ON Employee.EMPLOYEE_PK =
EmployeeRole.EMPLOYEE_ID) ON Role.ROLE_PK = EmployeeRole.ROLE_ID;
This is a SubQuery only--for next
qryEmployeeCourseForRole:
SELECT qryEmployeeCoursesForRoleSub.*, CourseRole.COURSE_ID
FROM qryEmployeeCoursesForRoleSub LEFT JOIN CourseRole ON qryEmployeeCoursesForRoleSub.ROLE_ID =
CourseRole.ROLE_ID;
This shows courserole with matching employeerole--a subquery for next
EmployeeCourseForRoleWAttended:
SELECT qryEmployeeCoursesForRole.*, IIf(IsNull([courseattendance_PK]),"No","Yes") AS Attended
FROM qryEmployeeCoursesForRole LEFT JOIN CourseAttendance ON (qryEmployeeCoursesForRole.COURSE_ID =
CourseAttendance.COURSE_ID) AND (qryEmployeeCoursesForRole.EMPLOYEE_ID =
CourseAttendance.EMPLOYEE_ID);
用于调试的其他示例数据
Employee Table:
Employee_PK Employee_Last Employee_First
Autonumber Daigle Jake
Autonumber Ryder Canen
Role Table:
Role_PK RoleName
5 Asset Shipper
6 Material Controller
7 Material MAnager
EmployeeRole Table:
EmployeeRole_PK Employee_ID Role_ID
Autonum Whatever Daigle is 5
Autonum Whatever Daigle is 1
Autonum Whatever Ryder is 5
Autonum Whatever Ryder is 6
Course Table:
Course_PK Course_Name Course_StartDate Course_EndDate
4 OTC 12/8/2011 12/9/2011
CourseRole Table:
CourseRole_PK Course_ID Role _ID
6 4 1
7 4 7
CourseAttendance:
CourseAttendance_PK Course_ID Employee_ID
Autonum 4 Whatever Daigle is
Autonum 4 Whatever Ryder is
好的,我发布了样本数据。如果用户参加了完成其中一个角色的课程并且courserole = employeerole然后查询报告他们已经完成了他们的所有角色,则会出现问题。
我需要一份报告:
员工姓氏,员工名字,角色1,CoureName,开始日期,结束日期,出席 但是,正如我在帖子开头列出的那样,逻辑将需要存在。
答案 0 :(得分:3)
它有点乱,但这应该让你开始。根据您上面的表格结构,您的设计有点偏。你有不必要的列表,但这不是你的问题。
这可以分为3个不同的查询,或者只使用UNION
,如下所示:
'this first query gets you the employees who have attended
SELECT E.EmployeeLast, E.EmployeeFirst, R.RoleName AS EmployeeRole
, C.CourseName, C.StartDate, C.EndDate, "Yes" AS Attended
FROM (((Employee AS E
INNER JOIN EmployeeRole AS ER
ON E.EmployeePK=ER.EmployeeId)
INNER JOIN Role AS R
ON ER.RoleID=R.RolePK)
LEFT JOIN CourseAttendance AS CA
ON E.EmployeePK=CA.EmployeeID)
LEFT JOIN Course AS C
ON CA.CourseID=C.CoursePK
WHERE E.EmployeePK IN (SELECT CA.EmployeeID
FROM ((CourseAttendance CA
INNER JOIN EmployeeRole ER
ON CA.EmployeeId = ER.EmployeeId)
INNER JOIN CourseRole CR
ON ER.RoleId = CR.RoleId
AND CA.CourseID = CR.CourseID));
UNION
'this second query gets you the employees who have not attended
SELECT E.EmployeeLast, E.EmployeeFirst, R.RoleName AS EmployeeRole
, C.CourseName, C.StartDate, C.EndDate, "No" AS Attended
FROM (((Employee AS E
INNER JOIN EmployeeRole AS ER
ON E.EmployeePK=ER.EmployeeId)
INNER JOIN Role AS R
ON ER.RoleID=R.RolePK)
LEFT JOIN CourseAttendance AS CA
ON E.EmployeePK=CA.EmployeeID)
LEFT JOIN Course AS C
ON CA.CourseID=C.CoursePK
WHERE E.EmployeePK NOT IN (SELECT CA.EmployeeID
FROM ((CourseAttendance CA
INNER JOIN EmployeeRole ER
ON CA.EmployeeId = ER.EmployeeId)
INNER JOIN CourseRole CR
ON ER.RoleId = CR.RoleId
AND CA.CourseID = CR.CourseID));
UNION
'this final query gets you the employees who have not attended and there is no course with their role
SELECT E.EmployeeLast, E.EmployeeFirst, R.RoleName AS EmployeeRole
, C.CourseName, C.StartDate, C.EndDate, "No Course With Role" AS Attended
FROM (((Employee AS E
INNER JOIN EmployeeRole AS ER
ON E.EmployeePK=ER.EmployeeId)
INNER JOIN Role AS R
ON ER.RoleID=R.RolePK)
LEFT JOIN CourseAttendance AS CA
ON E.EmployeePK=CA.EmployeeID)
LEFT JOIN Course AS C
ON CA.CourseID=C.CoursePK
WHERE ER.RoleID NOT IN (SELECT RoleID
FROM CourseRole)
AND E.EmployeePK NOT IN (SELECT CA.EmployeeID
FROM ((CourseAttendance CA
INNER JOIN EmployeeRole ER
ON CA.EmployeeId = ER.EmployeeId)
INNER JOIN CourseRole CR
ON ER.RoleId = CR.RoleId
AND CA.CourseID = CR.CourseID));