如果联接中的表没有行

时间:2016-08-17 03:04:19

标签: sql sql-server

我正在编写查询以选择有关测验(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,但我无法想到如何编写它。任何帮助将不胜感激。

4 个答案:

答案 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
     )