具有一点逻辑的高级查询

时间:2012-01-05 15:16:29

标签: ms-access logic ms-access-2007

我有一个高级查询/报告,我需要在Access 2007中创建帮助。 我需要生成的查询是:

Employee Last, Employee First, Employee Role, Course Name, StartDate, EndDate, Attended

我需要处理的逻辑是:

  1. 如果用户参加了employeeerole = courserole的课程, 出席=是
  2. 如果用户没有参加过Employeerole = courserole的课程, 出席=否
  3. 如果用户没有参加,并且没有匹配的课程 CourseRole,Attended =没有该角色的课程
  4. 一些额外的逻辑可能是添加: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,开始日期,结束日期,出席 但是,正如我在帖子开头列出的那样,逻辑将需要存在。

1 个答案:

答案 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));