我正在开发一个内部网Web应用程序,为用户提供简短的测验。测验将通过电子邮件发送给用户。我有以下数据库设计:
员工表:用户名,姓名,职位,分部ID
分区表:DivisionID,DivisionName
测验表:QuizID,标题,描述,IsSent
UserQuiz表:UserQuizID,Score,DateTimeComplete,QuizID,Username
注意:每个表中的第一个属性是主键。
对于您的信息,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
答案 0 :(得分:2)
最后发送的测验是
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
答案 1 :(得分:0)
我不是使用相关子查询(为每个行执行,因此执行效果不佳),而是使用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
答案 2 :(得分:0)
尝试:
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)