我正在开发一个类似于ASP.NET网站中的简单测验引擎。我有以下数据库设计:
用户表:用户名,名称,分区代码......等
分部表:SapCode,Division
测验表:QuizID,Title,IsSent,Description
UserQuiz:UserQuizID,QuizID,DateTimeComplete,Score,Username
每周,我公司的员工都会收到一封电子邮件通知,以参与系统中可用的新测验。将发送给员工的测验将具有(True)作为IsSent属性的值,这是将其与未发送给员工的其他测验区别开来的。我现在想要的是显示上次参加测验的参与者人数,因为每周只会发送一个测验。
我的查询显示所有参加测验的参与者总数:
SELECT dbo.Divisions.DivisionShortcut, COUNT(DISTINCT dbo.UserQuiz.Username) AS [Number of Participants], dbo.Quiz.QuizID
FROM dbo.Divisions INNER JOIN
dbo.employee ON dbo.Divisions.SapCode = dbo.employee.DivisionCode INNER JOIN
dbo.UserQuiz ON dbo.employee.Username = dbo.UserQuiz.Username INNER JOIN
dbo.Quiz ON dbo.UserQuiz.QuizID = dbo.Quiz.QuizID
WHERE (dbo.Quiz.IsSent = 1)
GROUP BY dbo.Divisions.DivisionShortcut, dbo.Quiz.QuizID
那么如何解决它只显示上次参加测验的参与者人数(发送的测验)?
答案 0 :(得分:1)
按IsSent = 1
的降序排列所有QuizID
个测验,然后选择第二个排名:
;
WITH SentQuizRanked AS (
SELECT
*,
ROW_NUMBER() OVER (ORDER BY QuizID DESC) AS rnk
FROM dbo.Quiz
WHERE IsSent = 1
)
SELECT
d.DivisionShortcut,
COUNT(DISTINCT uq.Username) AS [Number of Participants],
q.QuizID
FROM dbo.Divisions d
INNER JOIN dbo.Employee e ON d.SapCode = e.DivisionCode
INNER JOIN dbo.UserQuiz uq ON e.Username = uq.Username
INNER JOIN dbo.Quiz q ON uq.QuizID = q.QuizID
WHERE q.rnk = 2 /* the #1 quiz is the one being advertised,
so #2 is the last one taken */
GROUP BY
d.DivisionShortcut,
q.QuizID