Попытка создать запрос, который вернет все записи, поставила меня в тупик

#sql #ms-access

#sql #ms-access

Вопрос:

У меня есть база данных с тремя таблицами. «Реестр», «Учебные курсы» и «Регистрация на курс» Реестр и регистрация на курс связаны «ETID» (идентификатор обучения сотрудника). Регистрация на курс и учебные курсы связаны «Идентификатором курса».
Я пытаюсь создать запрос, который вернет ВСЕХ сотрудников и значение «ДА» / «НЕТ» для всех курсов. Я написал следующее, чтобы посмотреть на конкретных сотрудников, но, похоже, я не могу найти правильный способ вернуть всех сотрудников. Буду признателен за любую помощь.

 SELECT [TRAINING COURSES].[course id]
     , [TRAINING COURSES].[course name]
     , "YES" AS Completed
     , [COURSE ENROLLMENT].[training date]
FROM [TRAINING COURSES] 
INNER JOIN [COURSE ENROLLMENT]
            ON [COURSE ENROLLMENT].[course id]=[TRAINING COURSES].[course id]
WHERE [COURSE ENROLLMENT].[ETID]=[ENTER ETID]

UNION ALL 

SELECT [TRAINING COURSES].[course id]
     , [TRAINING COURSES].[course name]
     , "No" AS Completed
     , NULL
FROM [TRAINING COURSES]
WHERE NOT EXISTS 
(
    SELECT *
    FROM [COURSE ENROLLMENT]
    WHERE [COURSE ENROLLMENT].[course id]=[TRAINING COURSES].[course id] 
    AND [COURSE ENROLLMENT].[ETID]=[ENTER ETID:]
)
ORDER BY [TRAINING COURSES].[course name];
  

Комментарии:

1. Просто примечание: ваши запросы будет намного проще читать и записывать, если вы используете Pascal case: CourseEnrollment вместо [COURSE ENROLLMENT] . Вы можете предпочесть подчеркивание ( Course_Enrollment ), но, честно говоря, все лучше, чем заключать в квадратные скобки каждую таблицу и каждое поле.

2. Одно из величайших зол Access, ИМХО, заключается в том, что он допускает пробелы в именах объектов. И я не сторонник рефлексивного доступа….

3. Я разработчик Access с полной занятостью и не использовал пробелы в именах объектов с первых нескольких лет работы с ним. Просто через очень короткое время становится очевидным, что там нет никакой утилиты. Многие люди путают имена объектов с именами уровня представления, большинство из которых могут быть определены в ваших определениях объектов (например, свойство caption поля в таблице).

Ответ №1:

Вам не нужно использовать объединение в этом запросе. Замените ВНУТРЕННЕЕ соединение на ЛЕВОЕ ВНЕШНЕЕ соединение, и оно выполнит то же самое, что и ваш запрос, но будет работать лучше.

 SELECT [Training Courses].[Course Id], [Training Courses].[Course Name], 
        IIF(IsNull([Course Enrollment].[ETID]), "NO", "YES") as Completed,
        [Course Enrollment].[Training Date]
FROM    [Training Courses]
        LEFT OUTER JOIN [Course Enrollment]
            ON [Training Courses].[Course Id] = [Course Enrollment].[Course Id] 
ORDER BY [Training Courses].[Course Name]
  

Если вам нужны все сотрудники и все курсы, вам нужно выполнить перекрестное объединение между реестром и таблицей учебных курсов. Затем вы должны выполнить левое объединение с таблицей регистрации на курс, чтобы получить ответ «да», как указано выше.

Ответ №2:

Отбросьте WHERE [COURSE ENROLLMENT].[ETID]=[ENTER ETID] оба подзапроса.