#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]
оба подзапроса.