I have an advanced query/report that I need help creating in Access 2007.
The query I need generated is:
Employee Last, Employee First, Employee Role, Course Name, StartDate, EndDate, Attended
The Logic that I need to handle this is:
- IF user has attended a course with employeerole = courserole,
Attended = Yes - If user hasn’t attended a course with Employeerole = courserole,
Attended = No - If user hasn’t attended and there is not a Course with a Matching
CourseRole, Attended = No Course with that Role
Some additional logic that would be nice would be to add: Trainer Last to the Select
Logic: if Data isNull, Trainer Last = No Trainer Assigned
It wont let me post a picture of the database. So here is the Tables with Referential Entegrity:
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
So you can see it’s normalized and there are multiple Many to Many Tables which are required
PK is for Primary Key, ID is used as Foreign Key. So yes these are ok.
EDIT:
This query was posted in the comments:
I’ve tried a number of queries.
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);
This one doesnt handle the exception of 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
Now that i’ve walked through the logic in this much detail it appears this will require more than just a fancy query. If you need me to be more specific I can be but it’s going to require me to upload a document or something.
All Queries I’ve created and Reason for Query:
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);
Additional Sample data for debugging
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
Ok I posted the sample data. The problem occurs if a user has attended a course that fulfills one of their roles and the courserole = employeerole then the query is reporting that they have fulfilled ALL of their roles.
What I need in a single report:
Employee Last Name, Employee First Name, Role 1, CoureName, Start Date, End Date, Attended
But the logic will need to be there as I have it listed above at the beginning of the post.
Its kind of messy but this should get you started. Based on the table structures you have above, your design is a bit off. You have tables with unnecessary columns but that wasn’t your question.
This can be split into 3 different queries or just use a
UNIONas I did below: