我正在编写查询以选择有关测验(ModuleId
)上所有问题的信息。我需要最新的用户答案,以及问题,答案密钥和评分者信息(如果有的话)。
CREATE PROCEDURE spGetQuestionsAnswersMostRecentUserAnswersAndRevisions
(@UserId char(7), @ModuleId int)
AS
SELECT
ua.QuestionId, ua.UserAnswerId, UserAnswer, Question, Answer,
TypeId, GraderRevision, IsAnswerCorrect
FROM
UserAnswersByModule ua
INNER JOIN
QuestionsAnswersByModule qa ON qa.QuestionId = ua.QuestionId
INNER JOIN
GradedAnswersByQuestion ga ON ga.UserAnswerId = ua.UserAnswerId
WHERE
ua.UserAnswerId IN (SELECT MAX(UserAnswerId) AS MostRecentUserAnswer
FROM UserAnswersByModule
WHERE ModuleId = @ModuleId
AND UserId = @UserId
AND IsActive = 1
GROUP BY QuestionId)
AND ga.RevisionId IN (SELECT MAX(RevisionId) AS MostRecentRevisionId
FROM GradedAnswersByQuestion GA
INNER JOIN UserAnswersByModule ON ga.UserAnswerId = ua.UserAnswerId
WHERE UserId = @UserId
AND ModuleId = @ModuleId
GROUP BY GA.UserAnswerId)
这是表格的设置方式:
QuestionAnswersByModule :
PK - QuestionId
UserAnswersByModule :
PK - UserAnswerId
FK - QuestionAnswersByModule.QuestionId
GradedAnswersByQuestion :
PK - RevisionId
FK - UserAnswersByModule.UserAnswerId
我的查询存在的问题是,如果特定GradedAnswersByQuestion
的{{1}}中没有任何内容,则查询根本不返回任何内容,而不是这两列的空值其他信息。我很确定它是因为UserAnswerId
,但我无法想到如何编写它。任何帮助将不胜感激。
答案 0 :(得分:1)
根据定义,内部联接返回两个正在连接的表中包含的行。看看左右连接,看看它们是否符合您的预期目标。
答案 1 :(得分:0)
也许这可以通过最小的改变来实现......
CREATE PROCEDURE spGetQuestionsAnswersMostRecentUserAnswersAndRevisions(@UserId char(7),@ModuleId int) AS
SELECT ua.QuestionId, ua.UserAnswerId, UserAnswer, Question, Answer, TypeId, GraderRevision, IsAnswerCorrect
FROM UserAnswersByModule ua
INNER JOIN QuestionsAnswersByModule qa
ON qa.QuestionId = ua.QuestionId
LEFT OUTER JOIN GradedAnswersByQuestion ga /* <-- Changed! */
ON ga.UserAnswerId = ua.UserAnswerId
WHERE ua.UserAnswerId
IN (
SELECT MAX(UserAnswerId) AS MostRecentUserAnswer FROM UserAnswersByModule WHERE ModuleId = @ModuleId AND UserId = @UserId AND IsActive = 1 GROUP BY QuestionId
)
AND (
ga.RevisionId is null /* <-- Changed! */
OR ga.RevisionId IN (
SELECT MAX(RevisionId) AS MostRecentRevisionId
FROM GradedAnswersByQuestion GA
INNER JOIN UserAnswersByModule
ON ga.UserAnswerId = ua.UserAnswerId
WHERE UserId = @UserId
AND ModuleId = @ModuleId
GROUP BY GA.UserAnswerId
)
)
答案 2 :(得分:0)
CREATE PROCEDURE spGetQuestionsAnswersMostRecentUserAnswersAndRevisions
(
@UserId char(7),
@ModuleId int
) AS
SELECT
ua.QuestionId, ua.UserAnswerId,
UserAnswer, Question, Answer, TypeId, GraderRevision, IsAnswerCorrect
FROM
UserAnswersByModule ua
INNER JOIN QuestionsAnswersByModule qa
ON qa.QuestionId = ua.QuestionId
INNER JOIN GradedAnswersByQuestion ga
ON ga.UserAnswerId = ua.UserAnswerId
LEFT OUTER JOIN
(
SELECT MAX(RevisionId) AS MostRecentRevisionId
FROM GradedAnswersByQuestion GA
GROUP BY GA.UserAnswerId
) AS mr_ga
ON mr_ga.RevisionId = ga.RevisionId
WHERE
UserId = @UserId AND ModuleId = @ModuleId
AND ua.UserAnswerId IN (
SELECT MAX(UserAnswerId) AS MostRecentUserAnswer
FROM UserAnswersByModule
WHERE ModuleId = ua.ModuleId AND UserId = ua.UserId AND IsActive = 1
GROUP BY QuestionId
)
答案 3 :(得分:0)
写一个左连接并对其应用过滤条件。
CREATE PROCEDURE
spGetQuestionsAnswersMostRecentUserAnswersAndRevisions(@UserId char(7),@ModuleId int) AS
SELECT ua.QuestionId, ua.UserAnswerId, UserAnswer, Question, Answer, TypeId, GraderRevision, IsAnswerCorrect
FROM UserAnswersByModule ua
INNER JOIN QuestionsAnswersByModule qa
ON qa.QuestionId = ua.QuestionId
LEFT JOIN GradedAnswersByQuestion ga
ON ga.UserAnswerId = ua.UserAnswerId
AND ga.RevisionId IN (
SELECT
MAX(RevisionId) AS MostRecentRevisionId
FROM GradedAnswersByQuestion GA
INNER JOIN UserAnswersByModule
ON ga.UserAnswerId = ua.UserAnswerId
WHERE UserId = @UserId
AND ModuleId = @ModuleId
GROUP BY GA.UserAnswerId
)
Where ua.UserAnswerId IN (
SELECT MAX(UserAnswerId) AS MostRecentUserAnswer
FROM UserAnswersByModule
WHERE ModuleId = @ModuleId
AND UserId = @UserId
AND IsActive = 1 GROUP BY QuestionId
)