2012-01-05 2 views
1

J'ai une requête/rapport avancé que j'ai besoin d'aide pour créer dans Access 2007. La requête que je besoin généré est:Advanced Query avec un peu de logique

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

La logique que je dois gérer cela est :

  1. Si l'utilisateur a suivi un cours avec employeerole = courserole, = Oui assisté
  2. Si l'utilisateur n'a pas assisté à un cours avec Employeerole = courserole, = assisté Non
  3. Si l'utilisateur n'a pas assisté et il n'y a pas un cours avec unE CourseRole, Assisté = Non Cours avec ce rôle

Certains logique supplémentaire qui serait bien serait d'ajouter: Entraîneur dernier à le Choix
Logique: si les données sont nulles, formateur en dernier = aucun entraîneur assigné

Il ne me laisse pas poster une image de la base de données. Voici donc les tableaux avec référentielle 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 

Vous pouvez donc voir est normalisée et il y a plusieurs plusieurs à plusieurs tableaux qui sont nécessaires
PK est pour clé primaire, ID est utilisé comme clé étrangère. Alors oui, ça va.

EDIT:
Cette requête a été publiée dans les commentaires:
J'ai essayé un certain nombre de requêtes.

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

Celui-ci ne marche pas gérer l'exception de Non définie cours -

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 

Maintenant que je suis entré dans la logique dans ce détail qu'elle apparaît cela nécessitera plus qu'une simple requête de fantaisie. Si vous avez besoin que je sois plus précis, je peux l'être, mais il faudra que je télécharge un document ou quelque chose du genre.

toutes les requêtes que j'ai créé et la raison de la requête:

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

données supplémentaires de l'échantillon pour le débogage

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 j'ai posté les données d'échantillon. Le problème se produit si un utilisateur a suivi un cours qui remplit un de leurs rôles et le courserole = employeerole puis la requête rapporte qu'ils ont rempli tous leurs rôles.

Ce que je besoin dans un seul rapport:

employé Nom, prénom de l'employé, Rôle 1, CoureName, date de début, date de fin, Assisté Mais la logique devra être là que je l'ai répertorié ci-dessus au début du message.

+0

il y a quelques différences dans vos tables. d'abord, vous avez dans EmployeeRole un champ appelé Role_ID est ce Role_PK dans votre table de rôle? Dans votre table EmployeeRole, Employee_ID est-il également Employee_PK ou Employee_userid dans votre table Employee? – Taryn

+0

éditer votre question et poster quelques exemples de données serait utile – Taryn

+1

Surtout quand les gens disent des données d'échantillon, ils signifient de petites sections des tables pertinentes coupées et collées à la question. – Fionnuala

Répondre

3

Son genre de désordre mais cela devrait vous aider à démarrer. Basé sur les structures de table que vous avez ci-dessus, votre conception est un peu éteinte. Vous avez des tables avec des colonnes inutiles, mais ce n'était pas votre question.

Cela peut être divisé en 3 requêtes différentes ou simplement utiliser un UNION comme je l'ai fait ci-dessous:

'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)); 
+0

Je vais essayer maintenant. Je rapporterai après avoir modifié le script pour s'adapter à ma base de données – Piercy

+0

BlueFeet ... Je suis vraiment impressionné. Sur ma base de données de test que j'ai dû créer pour obtenir des exemples de données, cela fonctionne comme souhaité. Je vais le déplacer vers ma base de données de mise en scène et l'essayer. Je rapporterai. J'apprécie vraiment l'effort. – Piercy

+0

ok Je pense qu'il peut y avoir un problème avec la première requête. Quand j'ai jeté cela dans ma base de données de staging qui a des données plus réalistes, j'ai filtré les résultats à un seul rôle (ce rôle n'a aucun cours défini). Il est rapporté que certaines personnes ont suivi = Oui pour ce rôle et d'autres comme "Aucun cours avec rôle". Des pensées? – Piercy