2013-01-19 101 views
2

我有兩個表格,其中一個是問題,一個是答案。問題模式由問號,問題,模塊ID組成。一個模塊可能有很多問題。Sql:發現答案是否存在

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,我想如果返回「1」在特定的模塊id中的所有問題都可以在tblquestions中得到解答。 (一個問題在tblanswers中只有一個答案)或者如果不是所有問題都回答,則返回0。有關如何制定這種方法的任何幫助?

回答

4

也許有一些東西更容易,但這個應該工作,並能夠容易地修改它返回所有回答/沒有回答模塊或模塊的等失蹤的答案,。

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 

Here's the sql-fiddle與所有模塊的IDS,結果是:

  • 的moduleId = 1 => 1
  • 的moduleId = 2 => 1
  • 的moduleId = 3 => 0
+1

看起來太複雜了。 – Pedigree

+0

我認爲你可以把這些邏輯放到UDF/TVF中,如果有必要的話,也可以用'CROSS APPLY'。 –

+0

@CommanderOnets:但工作起來並且比「COUNT」方法更不容易出錯並且更容易擴展/更改。 –

2

將此查詢放入存儲過程中。

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過濾。

FULL存儲過程代碼

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 

UPDATE 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 
+1

現在可以工作,但是如果OP想要允許多個答案(也許invalids,版本化或刪除像SO這樣)或多項選擇,那麼它將不再工作。在我的觀點中,「COUNT」與「EXISTS」相比不那麼可靠並且更容易出錯。當我想知道它是否存在時,我爲什麼要計算一些東西? –

+0

@TimSchmelter即使OP允許每個問題有多個答案,這個陳述也只是稍作修改。 'COUNT(DISTINCT a.QuestionID)= COUNT(DISTINCT b.QuestionID)' –

+1

你沒有得到我的觀點。歸檔/版本/刪除答案不應該計算,多選答案不應該計算,因爲只有一個可能是必要的。但是,所有這些都可能受到'COUNT'很難處理的WHERE條款的限制。 –

0
I hope this may work.... 

declare @que int 
declare @ans int 
set @que=(select count(*) from Question where moduleid=1) 
set @ans=(select count(Answer.questionid) from Answer inner join Question 
on Question.Questionid=Answer.questionid where Question.moduleid=1) 
if(@que = @ans) 
begin 
    select 1 
end 
else 
begin 
    select 0 
end 
相關問題