#tsql
#tsql
Вопрос:
Здесь меня беспокоит другой запрос.
Select S.ID,S.Name,S.Surname,B.Title,SB.DateAndTimeIssued FROM Students S
INNER JOIN StudentBooks SB ON
S.ID = SB.StudentID
INNER JOIN Books B
ON B.ID = SB.BookID
WHERE B.ID = @BookID
Результаты:
1 | asd | asd | Book | 2011-10-12 18:31:40.557
1 | asd | asd | Gray Book | 2011-10-12 18:36:26.950
1 | asd | asd | Gray Book | 2011-10-12 18:36:34.137
Объяснение: Этот запрос возвращает мне имена и фамилии всех студентов, у которых была книга с определенным идентификатором, выданным им. Также отображаются дата и выданная им книга.
Проблема в том, что эти книги в таблице выше были назначены только одному студенту. Как я могу переписать этот запрос, чтобы показать мне, какие студенты не получили конкретную книгу с идентификатором @BookID ? Когда я использую WHERE NOT B.ID = @BookID
, он отправляет мне только имена студентов, которые не получили книгу, но получили книгу в прошлом.
Моя попытка:
SELECT S.Name,S.Surname FROM Students S
INNER JOIN StudentBooks SB
ON SB.StudentID = S.ID
INNER JOIN Books B
ON B.ID = SB.BookID
WHERE NOT SB.BookID = @BookID
Мне нужны имена студентов, которые вообще не получили книгу. Students, StudentBooks и Books — это отдельные таблицы, Students и Studentbooks находятся в отношениях «многие ко многим», поскольку книга может быть переиздана им позже, или копия книги может быть переиздана им, если они потеряли свои
Ответ №1:
Я думаю, вы можете объединить таблицу books и student books и получить все идентификаторы студентов, которые взяли книгу, а затем искать любой идентификатор в таблице student, которого нет в комбинации идентификаторов, которые вы получаете из первой таблицы (books и student books)
SELECT S.ID,S.Name,S.Surname,B.Title,SB.DateAndTimeIssued
FROM Students S
WHERE s.id NOT IN (SELECT id
FROM Books b
JOIN StudentBooks sb
ON b.ID = sb.BookID
WHERE b.ID = @BookID)
Комментарии:
1. Это сработало очень хорошо, большое вам спасибо. Вы сохранили мой rim. Теперь я могу закончить свой проект: D
2. Все, что я добавил в ваш код, это предложение where в подзапросе, чтобы посмотреть, где идентификатор книги = @BookID. Я получил желаемые результаты 🙂
Ответ №2:
Внешнее объединение, чтобы получить всех студентов, может быть, что-то вроде:
Select S.ID,S.Name,S.Surname,B.Title,SB.DateAndTimeIssued
FROM Students S
LEFT OUTER JOIN StudentBooks SB
ON S.ID = SB.StudentID
AND SB.BookId = @BookId
LEFT OUTER JOIN Books B
ON B.ID = SB.BookID
Который не будет включать заголовок для тех студентов, у которых нет записи в студенческой книжке, если вам нужен заголовок для каждой записи:
Select S.ID,S.Name,S.Surname,B.Title,SB.DateAndTimeIssued
FROM Students S
CROSS JOIN (select title from Books where Id = @BookId) B
LEFT OUTER JOIN StudentBooks SB
on SB.StudentId = S.ID
and SB.BookId = @BookId
Но я не понимаю результатов, которые вы показываете:
1 | asd | asd | Book | 2011-10-12 18:31:40.557
1 | asd | asd | Gray Book | 2011-10-12 18:36:26.950
1 | asd | asd | Gray Book | 2011-10-12 18:36:34.137
Насколько я понимаю ваш запрос, результат должен быть для одной конкретной книги на основе Book.Id = @BookID
, но вы показываете два разных названия книг: «Книга» и «Серая книга».
Как написано, ни один из этих запросов не обобщается для получения записей более чем для одного book.id за раз.