SQL: не удалось найти объединение или объединение для создания следующей таблицы

Таблица учеников с {ID, LastName}

предметная таблица с {ID, SubjectName}

и таблица отчета с {ID, PupilID, SubjectID, Grade}

Существует отношение «один ко многим» между таблицами учеников и отчетов, а также таблицами предметов и отчетов.

Я хочу создать такую ​​​​таблицу, например, для subjectID = 1

Pupil.ID  Pupil.LastName  SubjectID Grade

1 --------------Smith ---------- 1 ------------B
2 --------------Jones ---------- 1 ------------NULL
3 -------------Weston ----------1 ------------NULL    
4 -------------Knightly ---------1 -----------A

Проблема в том, что таблица отчетов будет содержать только 2 записи для субъекта 1:

PupilID  SubjectID  Grade

----1------- 1 ----------- B  
----4------- 1 ----------- A

Левые соединения, похоже, не работают, так как в таблице отчета есть только 2 записи для субъекта 1.

ОБРАЗЕЦ ДАННЫХ

{Pupil Table}

ID LastName    
1 ...Smith    
2 ...Jones    
3 ...Weston    
4 ...Knightly

{Subject Table}

ID SubjectName    
1 ....Maths    
2 ....Physics    
3 ....Chemistry

{Report Table}

ID PupilID SubjectID Grade    
1 .......1 ..........1 ..........B    
2 .......4 ..........1 ..........A

Когда я выполняю поиск по SubjectID = 1, мне нужна таблица:

Идентификатор ученика .......Фамилия ученика ........Идентификатор субъекта ...........Оценка

1 --------------Smith ---------- 1 ------------B
2 --------------Jones ---------- 1 ------------NULL
3 -------------Weston ----------1 ------------NULL
4 -------------Knightly ---------1 -----------A

person Philip    schedule 13.06.2017    source источник
comment
Какой клиент базы данных вы используете?   -  person SandPiper    schedule 14.06.2017
comment
Доступ (формат mdb)   -  person Philip    schedule 14.06.2017
comment
Предоставьте некоторые образцы данных из всех трех ваших таблиц.   -  person SandPiper    schedule 15.06.2017
comment
Добавлены образцы данных   -  person Philip    schedule 15.06.2017
comment
Смотрите обновленный ответ. У меня это работает.   -  person SandPiper    schedule 16.06.2017


Ответы (4)


Access не очень легко выполняет подзапросы, поэтому все втиснуто в предложение FROM с серией обернутых скобок. Основываясь на ваших примерных данных и моем боевом доступе, чтобы перестать быть излишне сложным, я придумал следующее:

SELECT ps.Pupil_ID, ps.LastName, ps.Subject_ID, r.Grade 
FROM (SELECT * FROM (SELECT ID AS Pupil_ID, LastName FROM Pupil) p, 
         (SELECT DISTINCT ID AS Subject_ID FROM Subject)) ps
     LEFT JOIN REPORT r ON r.PupilID = ps.Pupil_ID AND r.SubjectID = ps.Subject_ID
ORDER BY Pupil_ID, Subject_ID;

Подзапрос «ps» представляет собой декартово соединение представлений таблиц Pupil и Subject, которые я указал. На этом этапе ваш запрос будет выглядеть так:

(LastName column not shown for clarity)

StudentID|SubjectID
1         1
1         2
1         3
2         1
2         2
2         3
3         1
3         2
3         3

Теперь, используя этот подзапрос декартова соединения (pupilstudent -> ps), я использую ЛЕВОЕ СОЕДИНЕНИЕ, чтобы назначить таблицу отчета каждому уникальному идентификатору учащегося и идентификатору предмета. Поэтому, если учащийся не посещал определенный класс, в конечном результате будет значение NULL.

Я проверил это в Access, используя ваши образцы данных, и это работает на моей машине.

Также следует отметить, что использование поля с именем просто ID в каждой таблице является плохой практикой (например, в таблице учеников ID становится PupilID). Это делает его намного проще в использовании, и он сам документирует.

person SandPiper    schedule 14.06.2017
comment
Когда я пытаюсь: ВЫБЕРИТЕ ps.Pupil_ID, ps.LastName, ps.Subject_ID, r.Grade FROM (SELECT DISTINCT Pupil.ID AS Pupil_ID, Pupil.LastName FROM Pupil LEFT JOIN (SELECT DISTINCT Subject.ID AS Subject_ID FROM Subject) ON 1 =1) ps LEFT JOIN Report r ON r.PupilID = ps.Pupil_ID AND r.SubjectID = ps.Subject_ID ORDER BY Pupil_ID, Subject_ID Я все еще получаю сообщение об ошибке «Присоединение не поддерживается». - person Philip; 15.06.2017
comment
Я рад, что смог помочь! Если у вас больше нет проблем, отметьте это как принятый ответ. - person SandPiper; 16.06.2017

Перекрестное соединение таблиц учеников и предметов и левое соединение результатов с таблицей отчетов

person TJK    schedule 13.06.2017

Вам нужно перекрестное соединение:

SELECT Pupil.ID, Pupil.LastName, SubjectID, Grade FROM
Pupil, Subject LEFT JOIN Report ON Subject.ID=Report.SubjectID
WHERE Subject.ID=1
person Philip Tzou    schedule 13.06.2017
comment
Большое спасибо! Мой запрос относится к базе данных доступа (mdb), и он не принимает ЛЕВОЕ СОЕДИНЕНИЕ: ВЫБЕРИТЕ Pupil.ID, Pupil.LastName, SubjectID, Grade FROM Pupil, Subject LEFT JOIN Report ON Subject.ID=Report.SubjectID WHERE Subject. ID=1 Есть ли другой способ написать это, который будет принят базой данных доступа? - person Philip; 14.06.2017
comment
Access поддерживает левое соединение, я думаю, что это неявное соединение вызывает здесь проблемы. - person SandPiper; 14.06.2017
comment
@Philip Вы можете взглянуть на это: support.office.com/en-us/article/ - person Philip Tzou; 14.06.2017
comment
Я также пробовал: выберите * из Pupil p (выберите * из Subject, где id = 1) s left join Report on SubjectID = s.id и PupilID = p.id; В доступе это дает ошибку «Присоединение не поддерживается» - person Philip; 15.06.2017

Чтобы объединить каждого ученика с каждым (или с определенным) предметом, используйте перекрестное соединение; Затем используйте левое соединение, чтобы получить соответствующие оценки:

select *
from pupil p cross join (select * from subject where id = 1) s
left join report on subjectId = s.id and pupilId = p.id
person Stephan Lechner    schedule 13.06.2017