Как показать имена неучастников в последней отправляющей викторине в каждом подразделении? - PullRequest
1 голос
/ 06 марта 2012

Я занимаюсь разработкой веб-приложения для интрасети, которое предоставляет пользователям короткие тесты. Тесты будут отправлены пользователям по электронной почте. У меня есть следующий дизайн базы данных:

Таблица сотрудников: Имя пользователя, Имя, Работа, DivisionID

Таблица подразделений: DivisionID, DivisionName

Таблица теста: QuizID, заголовок, описание, IsSent

Таблица UserQuiz: UserQuizID, Счет, DateTimeComplete, QuizID, Имя пользователя

ПРИМЕЧАНИЕ. Первым атрибутом в каждой таблице является первичный ключ.

А для вашей информации IsSent - это флаг, используемый для определения того, какой тест отправляется пользователям, а какой нет.

Что мне нужно и нужно сейчас: Мне нужно составить запрос, который показывает имена неучастников в последней отправляющей викторине. Это означает, что если пользователям отправлено более одного теста, этот запрос должен отображать имена неучастников в последнем тесте отправки. Запрос также должен отображать DivisionName.

Я предложил следующий запрос, но он показывает неучастников во всех опросах в базе данных. Так как это изменить? или как получить то, что требуется выше?

SELECT     TOP (100) PERCENT Q.Title, D.DivisionShortcut, E.Name
FROM         dbo.Quiz AS Q CROSS JOIN
                      dbo.employee AS E LEFT OUTER JOIN
                      dbo.Divisions AS D ON E.DivisionCode = D.SapCode
WHERE     (NOT EXISTS
                          (SELECT     UserQuizID, QuizID, DateTimeComplete, Score, Username
                            FROM          dbo.UserQuiz AS UQ
                            WHERE      (Username = E.Username) AND (QuizID = Q.QuizID)))
ORDER BY Q.Title, D.DivisionShortcut

Ответы [ 3 ]

2 голосов
/ 06 марта 2012

Последний отправленный тест -

select max(quizID) from dbo.Quiz where IsSent = 1

пользователей, которые участвовали в последней викторине:

select A.QuizID, a.Username 
from UserQuiz a join 
 (select max(quizID) quizID from dbo.Quiz where IsSent = 1) b
  on a.QuizId = b.quizID

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

select u.name, d.DivisionName
from
  users u
  join Divisions d on (u.divisionID = d.divisionID)
  left join 
    (select A.QuizID, a.Username 
     from UserQuiz a join 
     (select max(quizID) quizID from dbo.Quiz where IsSent = 1) b
     on a.QuizId = b.quizID
     ) c
   on u.username = c.username
 where c.QuizID is null
0 голосов
/ 06 марта 2012

Попробуйте:

select q.Title, d.DivisionShortcut, e.Name
from (select top 1 * from Quiz where IsSent = 1 order by QuizID desc) q
cross join Employee e
join Division d on e.divisionID = d.divisionID
where not exists
(select null from UserQuiz uq
 where uq.QuizID = q.QuizID and uq.Username = e.Username)
0 голосов
/ 06 марта 2012

Вместо того, чтобы использовать коррелированный подзапрос (который выполняется для каждой строки и, следовательно, является плохо выполняемым запросом), я бы выразил его с помощью NOT IN и упростил бы все это, например, так::

SELECT Q.Title, D.DivisionShortcut, E.Name
FROM (
    SELECT Title, QuizID
    FROM UserQuiz
    WHERE QuizID = (SELECT MAX(QuizID) FROM UserQuiz)) Q
CROSS JOIN employee E
JOIN Divisions D ON E.DivisionCode = D.SapCode
WHERE E.Username NOT IN (
    SELECT Username
    FROM UserQuiz
    WHERE QuizID = Q.QuizID)
ORDER BY Q.Title, D.DivisionShortcut
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...