我正在为考试注册和评分构建软件:
我需要从这两个表中获取数据:
考试
|------------------------------------------------------------|
| ExamId | ExamTitle | EducationId | ExamDate |
|------------------------------------------------------------|
ExamAttempts
|-----------------------------------------------------------------------------|
| ExamAttemptId | ExamId | StudentId | Grade | NotPresentCode |
|-----------------------------------------------------------------------------|
如果符合以下条件,学生可以报名参加考试: - 尚未通过(2级以下) - 尚未使用所有尝试
我想列出学生可以注册的每一项考试。
这可能相当简单,但我无法理解它,现在我被困住了!我已经尝试了一切,但还没有把它弄好。这是我做出的更无望的尝试之一(!):
CREATE PROCEDURE getExamsOpenForSignUp
@EducationId int,
@StudentId int
AS
SELECT ex.*
FROM Exams ex
LEFT JOIN (
SELECT ExamId, COUNT(ExamId) AS NumAttempts
FROM ExamAttempts
WHERE StudentId = @StudentId AND grade < 2 OR grade IS NULL
GROUP BY ExamId
) exGrouped ON ex.ExamId = exGrouped.ExamId
WHERE educationid = @EducationId and exGrouped.ExamId IS NULL OR exGrouped.NumAttempts < 6;
GO
我做错了什么?请帮忙......
答案 0 :(得分:1)
您需要从考试和学生的所有可能性列表开始,然后淘汰不符合要求的那些。
select driver.StudentId, driver.ExamId
from (select @StudentId as StudentId, e.ExamId
from exams e
where e.EducationId = @EducationId
) driver left outer join
(select ea.ExamId, ea.StudentId
from ExamAttempts ea
group by ea.ExamId, ea.StudentId
having max(grade) >= 2 or -- passed
count(*) >= 6
) NotEligible
on driver.ExamId = NotEligible.ExamId and
driver.StudentId = NotEligible.StudentId
where NotEligible.ExamId is NULL
此查询的结构非常具体。 driver
表包含所有可能的组合。在这种情况下,您只有一名学生,所有考试都在“教育”中。然后左连接根据您的两个要求确定哪些不符合条件。最终where
选择不符合条件的不匹配项或符合条件的考试。
答案 1 :(得分:1)
检查您的SP是否有效:
Select EduExams.ExamId
from
(select * from Exams
where Exams.EducationId = @EducationId) EduExams
left outer join
(select * from ExamAttempts
where ExamAttempts.StudentId = @StudentId) StudentAttempts
on EduExams.ExamID = StudentAttempts.ExamId
group by EduExams.ExamId
having count(StudentAttempts.ExamAttemptId) < 6
and ((max(StudentAttempts.Grade) is null) or (max(StudentAttempts.Grade) < 2))
答案 2 :(得分:0)
好的,谢谢你们的帮助 - 非常感谢!
基于@Gordon Linoffs解决方案。这就是我最终的结果:
SELECT driver.ExamId, driver.ExamTitle
FROM (
SELECT @StudentId AS StudentId, e.ExamId, e.ExamTitle
FROM exams e
WHERE e.EducationId = @EducationId
) driver
LEFT JOIN (
SELECT ea.ExamId, ea.StudentId
FROM ExamAttempts ea
WHERE ea.studentId = @StudentId
GROUP BY ea.ExamId, ea.StudentId
HAVING MAX(grade) >= 2 OR COUNT(*) >= 6
) NotEligible
ON driver.ExamId = NotEligible.ExamId AND driver.StudentId = NotEligible.StudentId
WHERE NotEligible.ExamId IS NULL