I have an “Answer” database table below:
Answer Table
AnswerId SessionId QuestionId Answer
13 AAA 1 A
14 AAC 1 True
Now as you can see there is 1 answer for question 1 in Exam (Session) AAA, and these is 1 answer for question 1 in Exam (Session) AAC.
Below is the “Question” Table:
Question Table:
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
Now I have a search function where the user enters in a term from a question and compiles the search. So for example if the user enters in “2+2”, then below is what the results should display in the php/html table:
QuestionContent Option Type Number of Answers Answer Number of Replies Number of Marks
What is 2+2? A-D 1 A Single 5
But the problem is that it is displaying an extra row, it is displaying this below:
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
Now what my question is that why is it displaying two rows and why is it including the answer “True” under the “Answer” column when the answer for that question should just be “A”? I believe it is because both questions have the same QuestionId (Question number) but they both belong to different SessionId’s so this should not be a problem.
Below is the code (Which I have reduced so it is easier for you to read and hopefully see the problem) where it performs the query and outputs the results:
<?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;
}
?>
The problem here seems about your db schema you defined is not the way you use it, I mean it seems the unique value on the Answer Table should be answerID or SessionId+QuestionId, so if you use that table in a query you should also include SessionId in your join condition with Question table, I mean here at least it looks two different questions in different session can have same questionID is the key problem.
So your code should something like following:
The SQL query above UPDATED to reflect to the updated question
The new problem still related with the same thing which is the query did not specify session so different question across session might be mixed together, I suggest you query out the sessionID in your select list for grabbing correct data, and hide it on the page if you don’t want show it, however keep in mind you need to record that if you have some other detail page to show the question you still need to pass sessionID and QuestionId altogether to that page for identify the unique data