2016-08-17 2 views
1

Ich schreibe eine Abfrage, um Informationen zu allen Fragen zu einem Quiz auszuwählen (ModuleId). Ich brauche die letzte Benutzerantwort, zusammen mit der Frage, dem Antwortschlüssel und den Informationen für den Schüler, falls vorhanden.Keine Zeilen ausgewählt, wenn die Tabelle im Join keine Zeile enthält

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) 

Dies ist, wie die Tabellen eingerichtet sind:

QuestionAnswersByModule:

PK - QuestionId 

UserAnswersByModule:

PK - UserAnswerId 
FK - QuestionAnswersByModule.QuestionId 

GradedAnswersByQuestion:

PK - RevisionId 
FK - UserAnswersByModule.UserAnswerId 

Das Problem mit meiner Anfrage ist, dass, wenn es in GradedAnswersByQuestion für die jeweiligen UserAnswerId nichts ist, die Abfrage gar nichts zurückzugibt, statt null für diese beiden Spalten und den Rest die Information. Ich bin mir ziemlich sicher, dass es wegen der AND ga.RevisionId IN ... ist, aber ich kann mir nicht vorstellen, wie ich es sonst schreiben könnte. Jede Hilfe wäre willkommen.

Antwort

0

Vielleicht tut dies den Trick mit minimalen Änderungen ...

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 
) 
) 
+0

Vielen Dank für Ihren Vorschlag, ich habe Ihre Version versucht und ich bekomme immer noch die gleichen Ergebnisse. Wenn ich die Abfrage mit leeren Zeilen in der abgestuften Tabelle ausführe, wird nichts zurückgegeben. Ich wollte feststellen, dass ich Links Joins versucht habe, aber nicht weiter kommen konnte. Bearbeiten - Eigentlich habe ich eine der Änderungen verpasst, lassen Sie mich es erneut versuchen und ich werde Sie wissen lassen, ob es funktioniert. – kjstan

+0

Ich entschuldige mich, Ihr Vorschlag hat funktioniert! Vielen Dank! – kjstan

+0

Ok. Großartig, ich würde eine andere Version anbieten, aber ich denke, das wird nicht nötig sein! – shawnt00

1

einem inneren definitions beitreten gibt Zeilen, die in beiden Tabellen enthalten sind, die miteinander verbunden sind. Werfen Sie einen Blick auf die linken und rechten Joins und sehen Sie, ob sie zu Ihrem beabsichtigten Ziel passen.

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 
    ) 
0

Schreiben Sie einen linken Join und wenden Sie Filterbedingung darauf an.

Verwandte Themen