0

以下に「Answer」データベーステーブルがあります。

回答表

AnswerId SessionId QuestionId Answer
13       AAA       1          A
14       AAC       1          True

ご覧のとおり、試験(セッション)AAAの質問1には1つの回答があり、試験(セッション)AACの質問1には1つの回答があります。

以下は「質問」の表です。

質問表:

SessionId  QuestionId QuestionContent NoofAnswers ReplyId QuestionMarks OptionId
AAA        1          What is 2+2?    1           1       5             2
AAC        1          Is 3+3 = 6?     1           1       5             25

これで、ユーザーが質問から用語を入力して検索をコンパイルする検索機能ができました。したがって、たとえば、ユーザーが「2 + 2」と入力した場合、以下はphp/htmlテーブルに表示される結果です。

   QuestionContent Option Type  Number of Answers Answer Number of Replies  Number of Marks
   What is 2+2?    A-D          1                 A      Single             5

しかし、問題はそれが余分な行を表示していることです、それはこれを以下に表示しています:

   QuestionContent Option Type  Number of Answers Answer Number of Replies  Number of Marks
   What is 2+2?    A-D          1                 A True    Single             5
   What is 2+2?    A-D          1                 A True    Single             5

さて、私の質問は、なぜ2行が表示されるのか、そしてその質問の答えが「A」である必要があるのに、「Answer」列の下に「True」という答えが含まれているのはなぜですか。両方の質問が同じQuestionId(質問番号)を持っているが、両方とも異なるSessionIdに属しているため、これは問題ではないはずです。

以下は、クエリを実行して結果を出力するコード(私が削減したもので、読みやすく、うまくいけば問題を確認しやすくなっています)です。

<?php

//connect to db


    // Build the query
    $questionquery = "
SELECT DISTINCT q.QuestionContent, o.OptionType, q.NoofAnswers, GROUP_CONCAT(DISTINCT Answer SEPARATOR '') AS Answer, r.ReplyType, 
       q.QuestionMarks 
  FROM Answer an 
  INNER JOIN Question q ON q.QuestionId = an.QuestionId
  JOIN Reply r ON q.ReplyId = r.ReplyId 
  JOIN Option_Table o ON q.OptionId = o.OptionId 
      WHERE ".implode(" AND ", array_fill(0, $numTerms, "q.QuestionContent LIKE ?"))."
      GROUP BY an.SessionId, an.QuestionId
      ORDER BY ".implode(", ", array_fill(0, $numTerms, "IF(q.QuestionContent LIKE ?, 1, 0) DESC"))."
    ";

    // Make the referenced array
    $referencedArray = make_values_referenced(array_merge(
      array(str_repeat("ss", $numTerms)), // types
      $termArray,                         // where
      $termArray                          // order by
    ));


    // Bind parameters
    if (!call_user_func_array(array($stmt, 'bind_param'), make_values_referenced($referencedArray))) {
      die("Error binding parameters: $stmt->error"); 
    }


    // This will hold the search results
    $searchResults = array();
    $searchOption = array();
    $searchNoofAnswers = array();
    $searchAnswer = array();
    $searchReply = array();
    $searchMarks = array();

    // Fetch the results into an array
    if (!$stmt->num_rows()) {
      $stmt->bind_result($dbQuestionContent,$dbOptionType,$dbNoofAnswers,$dbAnswer,$dbReplyType,$dbQuestionMarks); 
      while ($stmt->fetch()) {
        $searchResults[] = $dbQuestionContent;
        $searchOption[] = $dbOptionType;
        $searchNoofAnswers[] = $dbNoofAnswers;
        $searchAnswer[] = $dbAnswer;
        $searchReply[] = $dbReplyType;
        $searchMarks[] = $dbQuestionMarks;
      }
    }

  }


      $questionnum = sizeof($searchResults);

    // If $searchResults is not empty we got results
    if (!empty($searchResults)) {
      echo "<p>Your Search: '$inputValue'</p>";  
      echo"<p>Number of Questions Shown from the Search: <strong>$questionnum</strong></p>";
      echo "<table border='1' id='resulttbl'>
      <tr>
      <th class='questionth'>Question</th>
      <th class='optiontypeth'>Option Type</th>
      <th class='noofanswersth'>Number of <br/> Answers</th>
      <th class='answerth'>Answer</th>
      <th class='noofrepliesth'>Number of <br/> Replies</th>
      <th class='noofmarksth'>Number of <br/> Marks</th>
      </tr>\n";
      $script = '';
      foreach ($searchResults as $key=>$question) {
      $script .= 'var key_' . $key . '="' . str_replace('"','\"', $question) . '";' . PHP_EOL;
        echo '<tr class="questiontd">'.PHP_EOL;
        echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
        echo '<td class="optiontypetd">'.htmlspecialchars($searchOption[$key]).'</td>' . PHP_EOL;
        echo '<td class="noofanswerstd">'.htmlspecialchars($searchNoofAnswers[$key]).'</td>' . PHP_EOL;
        echo '<td class="answertd">'.htmlspecialchars(implode(' ', $searchAnswer)).'</td>' . PHP_EOL; 
        echo '<td class="noofrepliestd">'.htmlspecialchars($searchReply[$key]).'</td>' . PHP_EOL;
        echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
        echo "<td class='addtd'><button type='button' class='add' onclick=\"parent.addwindow(key_$key,'$searchMarks[$key]','$searchNoofAnswers[$key]','$searchOption[$key]','$searchReply[$key]','$searchAnswer[$key]');\">Add</button></td></tr>";
}
        echo "</table>" . PHP_EOL;
        echo '<script type="text/javascript">' . PHP_EOL;
        echo $script;
        echo '</script>' . PHP_EOL;


}
?>
4

2 に答える 2

1

ここでの問題は、定義したデータベーススキーマが使用方法ではないようです。つまり、回答テーブルの一意の値はanswerIDまたはSessionId + QuestionIdである必要があるため、クエリでそのテーブルを使用する場合は、そのテーブルも含める必要があります。質問テーブルとの結合条件のSessionId、つまり、少なくともここでは、異なるセッションの2つの異なる質問が同じquestionIDを持つ可能性があるように見えます。これが重要な問題です。

したがって、コードは次のようになります。

SELECT DISTINCT q.QuestionContent, o.OptionType, q.NoofAnswers, GROUP_CONCAT(DISTINCT     Answer SEPARATOR '') AS Answer, r.ReplyType, 
       q.QuestionMarks, q.SessionId
FROM Answer an 
INNER JOIN Question q ON q.QuestionId = an.QuestionId and an.SessionId = q.SessionId
JOIN Reply r ON q.ReplyId = r.ReplyId 
JOIN Option_Table o ON q.OptionId = o.OptionId 
    WHERE ".implode(" AND ", array_fill(0, $numTerms, "q.QuestionContent LIKE ?"))."
    GROUP BY an.SessionId, an.QuestionId
    ORDER BY ".implode(", ", array_fill(0, $numTerms, "IF(q.QuestionContent LIKE ?, 1, 0) DESC"))."
";

更新された質問に反映するために更新された上記のSQLクエリ

クエリがセッションを指定しなかったため、セッション間で異なる質問が混在する可能性があるという同じ問題に関連する新しい問題は、正しいデータを取得するために選択リストでsessionIDをクエリし、ページに非表示にすることをお勧めします。表示したくない場合でも、質問を表示する他の詳細ページがある場合は、一意のデータを識別するために、sessionIDとQuestionIdをすべてそのページに渡す必要があることを記録する必要があることに注意してください。

于 2012-10-11T02:14:57.290 に答える
0

an.QuestionId選択クエリに含めます。

$questionquery = "
SELECT DISTINCT an.QuestionId,q.QuestionContent, o.OptionType, q.NoofAnswers, GROUP_CONCAT(DISTINCT Answer SEPARATOR '') AS Answer, r.ReplyType, 
   q.QuestionMarks 
FROM Answer an 
INNER JOIN Question q ON q.QuestionId = an.QuestionId
JOIN Reply r ON q.ReplyId = r.ReplyId 
JOIN Option_Table o ON q.OptionId = o.OptionId 
  WHERE ".implode(" AND ", array_fill(0, $numTerms, "q.QuestionContent LIKE ?"))."
  GROUP BY an.SessionId, an.QuestionId
  ORDER BY ".implode(", ", array_fill(0, $numTerms, "IF(q.QuestionContent LIKE ?, 1, 0)  DESC"))."
 ";

group by forを使用しましan.QuestionIdたが、この複数のデータが来るため、これをselect列に含めませんでした。

于 2012-10-11T02:11:43.963 に答える