Sql:查找答案是否存在

Sql:查找答案是否存在,sql,sql-server,sql-server-2008,stored-procedures,Sql,Sql Server,Sql Server 2008,Stored Procedures,我有两张桌子,一张有问题,一张有答案。问题模式由问题id、问题、模块id组成。一个模块id可能有许多问题 Questionid Question Moduleid(FK) -------- ----- ------- 1 q1 1 2 q2 1 3 q4 2 4 q5 2 答案模式由

我有两张桌子,一张有问题,一张有答案。问题模式由问题id、问题、模块id组成。一个模块id可能有许多问题

Questionid   Question    Moduleid(FK)
--------     -----       -------
1            q1             1
2            q2             1
3            q4             2
4            q5             2
答案模式由3列组成

answerid     Answer    questionid(FK)
--------     -----       -------
1            a1             1
2            a2             2
3            a4             3
4            a5             4

我正在尝试构造一个存储过程,我将把tblquestions的@moduleid作为参数发送,如果特定moduleid的所有问题都在tblquestions中得到了回答,我希望它返回“1”。(一个问题在tblanswers中只有一个答案)或如果不是所有问题都得到回答,则返回0。有关如何使用此方法的任何帮助?

将此查询放入存储过程中

SELECT  CASE WHEN (COUNT(a.QuestionID) = COUNT(b.QuestionID))
            THEN 1 
            ELSE 0
        END as AreAllAnswered
FROM    questions a
        LEFT JOIN answers b
            ON a.QuestionID = b.questionID
WHERE   a.ModuleID = @valueHere
之所以看不到
GROUP BY
子句,是因为记录已仅按特定的
ModuleID
进行筛选

完整存储过程代码

CREATE PROCEDURE ProcNameHere (@ModuleID INTEGER) 
AS 
    SELECT  CASE WHEN (COUNT(a.QuestionID) = COUNT(b.QuestionID))
                THEN 1 
                ELSE 0
            END as AreAllAnswered
    FROM    questions a
            LEFT JOIN answers b
                ON a.QuestionID = b.questionID
    WHERE   a.ModuleID = @ModuleID
GO
更新1

如果OP允许每个问题都有多个答案,那么查询只需稍加修改

CREATE PROCEDURE ProcNameHere (@ModuleID INTEGER) 
AS 
    SELECT  CASE WHEN (COUNT(DISTINCT a.QuestionID) = COUNT(DISTINCT b.QuestionID))
                THEN 1 
                ELSE 0
            END as AreAllAnswered
    FROM    questions a
            LEFT JOIN answers b
                ON a.QuestionID = b.questionID
    WHERE   a.ModuleID = @ModuleID
GO

也许有更简单的方法,但这应该可以工作,并且可以轻松地修改它,以返回所有已回答/未回答的模块或模块的缺失答案等

SELECT CASE 
     WHEN EXISTS (SELECT 1 
                  FROM   tblquestions AS q 
                         INNER JOIN tblanswers AS a 
                                 ON q.questionid = a.questionid 
                  WHERE  ( q.moduleid = @ModuleId ) 
                         AND ( NOT EXISTS (SELECT 1 
                                           FROM   tblquestions AS q 
                                                  LEFT OUTER JOIN 
                                                  tblanswers AS a 
                                                               ON 
                                                  q.questionid = 
                                                  a.questionid 
                                           WHERE  ( q.moduleid = @ModuleId ) 
                                                  AND ( a.answerid IS NULL ) 
                                          ) )) 
   THEN 1  ELSE 0 
   END  AS AllQuestionsAnswered
对于所有模块ID,结果如下:

  • ModuleID=1=>1
  • ModuleID=2=>1
  • ModuleID=3=>0

现在可以工作了,但如果OP希望允许多个答案(可能是无效答案、版本控制答案或删除答案,如本文所述)或多项选择,那么它将不再工作。在我看来,
COUNT
比现有的
更少可维护,更容易出错。当我想知道某件事是否存在时,为什么我要数一数呢?@TimSchmelter即使OP允许每个问题有多个答案,这句话也只是稍加修改<代码>计数(不同的a.QuestionID)=计数(不同的b.QuestionID)
你没有理解我的意思。存档/版本化/删除的答案不应计算在内,多选答案不应计算在内,因为可能只需要一个答案。但所有这些都可能受到
WHERE
子句的约束,这对于
COUNT
来说是很困难的。我认为您可以将一些逻辑放入UDF/TVF中,如果必要的话,
交叉应用
它。@CommanderOnets:But有效,并且比
计数
方法更不容易出错,更容易扩展/更改。@TimSchmelter有效,但我如何为返回结果的列命名?@TimSchmelter
+1
使用纯
ANSI
(变量除外)以及
存在
:)
SELECT CASE 
     WHEN EXISTS (SELECT 1 
                  FROM   tblquestions AS q 
                         INNER JOIN tblanswers AS a 
                                 ON q.questionid = a.questionid 
                  WHERE  ( q.moduleid = @ModuleId ) 
                         AND ( NOT EXISTS (SELECT 1 
                                           FROM   tblquestions AS q 
                                                  LEFT OUTER JOIN 
                                                  tblanswers AS a 
                                                               ON 
                                                  q.questionid = 
                                                  a.questionid 
                                           WHERE  ( q.moduleid = @ModuleId ) 
                                                  AND ( a.answerid IS NULL ) 
                                          ) )) 
   THEN 1  ELSE 0 
   END  AS AllQuestionsAnswered