I am having trouble with looping through data when selecting an All option in one or both of relevant drop down menus. It is not going through all the records and displaying them, it is only going trough one set of data. It is suppose to display details for each student and for each question they have participated in. But it is only showing one student and one question and that is all.
Below is what it should display:

But instead at the moment it is just displaying this:

I believe what is causing this problem is the dynamic WHERE clause I have set up. Below is how dynamic WHERE clause works:
- Compulsory WHERE condition of
q.SessionId = ? - If user selects single student from student drop down menu, then add
AND sa.StudentId = ?to WHERE clause - If user selects
Allstudents option from student drop down menu, then remove or do not displayAND sa.StudentId = ?from WHERE clause - If user selects single question from question drop down menu, then add
AND q.QuestionId = ?to WHERE clause - If user selects
Allquestions option from question drop down menu, then remove or do not displayAND q.QuestionId = ?from WHERE clause
I have three drop down menus (below is what they look like with sample data):
Session:
<select name="session" id="sessionsDrop">
<option value="26">POKUB1</option>
<option value="27">POKUB2</option>
</select>
Student:
<select name="student" id="studentsDrop">
<option value="0">All</option>
<option value="39">Luke Mcfadzen</option>
<option value="40">Chris Tucker</option>
</select>
Question:
<select name="question" id="questionsDrop">
<option value="0">All</option>
<option value="72">1</option>
<option value="73">2</option>
</select>
Don’t forget how the WHERE condition is suppose to work which I mentioned above in this question. Lets say the session chosen from session drop down menu is POKUB 1, drop down value: 26.
If you select a single student and a single question, then it displays the details correctly e.g.
- Student: Luke McFadzen – drop down value: 39
- Question: 1 – drop down value: 72
So WHERE condition is q.SessionId = 26 AND sa.StudentId = 39 AND q.QuestionId = 72.
But if I select an All option in either or both student and question drop down menu, then the output only displays one student and one question and for some strange reason it combines answers from all questions and combines all student answer answers into the single output.
Now All option in both drop down menus has a drop down value of 0, now 0 is not a value to select from database but we have stated in dynamic where clause that if a 0 value is chosen from a specific drop down menu, then remove the relevant condition from the WHERE clause, so for example:
Allstudents and single question (value72) –WHERE q.SessionId
= 26 AND q.QuestionId = 72- Single (value
39) student andAllquestions –WHERE q.SessionId
= 26 AND sa.StudentId = 39 Allstudents andAllquestions –WHERE q.SessionId = 26
THE ABOVE SCENARIOS ARE HAVING THE PROBLEMS
If I just left the query with a static WHERE clause WHERE q.SessionId = ? then it outputs the details correctly if I select All students and All Questions, but I need the query to work for all different possible options selected from the drop down menus and hence why I need a dynamic WHERE clause. How can I get it to work so the correct details are outputted?
Code:
$selectedstudentanswerqry = "
SELECT
sa.StudentId, StudentAlias, StudentForename, StudentSurname, q.SessionId,
q.QuestionId, QuestionNo, QuestionContent, o.OptionType, q.NoofAnswers,
GROUP_CONCAT( DISTINCT Answer ORDER BY Answer SEPARATOR ',' ) AS Answer, r.ReplyType, QuestionMarks,
GROUP_CONCAT(DISTINCT StudentAnswer ORDER BY StudentAnswer SEPARATOR ',') AS StudentAnswer, ResponseTime, MouseClick,
(
SELECT sum( StudentMark )
FROM Student_Answer sta
WHERE sa.StudentId = sta.StudentId
AND sa.QuestionId = sta.QuestionId
)StudentMark
FROM Student st
INNER JOIN Student_Answer sa ON (st.StudentId = sa.StudentId)
INNER JOIN Student_Response sr ON (sa.StudentId = sr.StudentId) AND sa.QuestionId = sr.QuestionId
INNER JOIN Question q ON (sa.QuestionId = q.QuestionId)
INNER JOIN Answer an ON q.QuestionId = an.QuestionId
LEFT JOIN Reply r ON q.ReplyId = r.ReplyId
LEFT JOIN Option_Table o ON q.OptionId = o.OptionId
";
// Initially empty
$where = array('q.SessionId = ?');
$parameters = array($_POST["session"]);
$parameterTypes = 'i';
//check if POST is empty
// Check whether a specific student was selected
$p_student = empty($_POST["student"])?'':$_POST["student"];
switch($p_student){
case 0:
//dont' add where filters
break;
default:
$where[] = 'sa.StudentId = ?';
$parameters[] .= $_POST["student"];
$parameterTypes .= 'i';
}
// Check whether a specific question was selected
$p_question = empty($_POST["question"])?'':$_POST["question"];
switch($p_question){
case 0:
//dont' add where filters
break;
default:
$where[] = 'q.QuestionId = ?';
$parameters[] .= $_POST["question"];
$parameterTypes .= 'i';
}
// If we added to $where in any of the conditionals, we need a WHERE clause in
// our query
if(!empty($where)) {
$selectedstudentanswerqry .= ' WHERE ' . implode(' AND ', $where);
global $mysqli;
$selectedstudentanswerstmt=$mysqli->prepare($selectedstudentanswerqry);
// You only need to call bind_param once
if (count($where) == 1) {
$selectedstudentanswerstmt->bind_param($parameterTypes, $parameters[0]);
}
else if (count($where) == 2) {
$selectedstudentanswerstmt->bind_param($parameterTypes, $parameters[0], $parameters[1]);
}
else if (count($where) == 3) {
$selectedstudentanswerstmt->bind_param($parameterTypes, $parameters[0], $parameters[1], $parameters[2]);
}
}
$selectedstudentanswerqry .= "
GROUP BY sa.StudentId, q.QuestionId
ORDER BY StudentAlias, q.SessionId, QuestionNo
";
// get result and assign variables (prefix with db)
$selectedstudentanswerstmt->execute();
$selectedstudentanswerstmt->bind_result($detailsStudentId,$detailsStudentAlias,$detailsStudentForename,$detailsStudentSurname,$detailsSessionId,
$detailsQuestionId,$detailsQuestionNo,$detailsQuestionContent,$detailsOptionType,$detailsNoofAnswers,$detailsAnswer,$detailsReplyType,$detailsQuestionMarks,
$detailsStudentAnswer,$detailsResponseTime,$detailsMouseClick,$detailsStudentMark);
$selectedstudentanswerstmt->store_result();
$selectedstudentanswernum = $selectedstudentanswerstmt->num_rows();
while ($selectedstudentanswerstmt->fetch()) {
//Check if the student data exist.
if (!isset($questions[$detailsStudentId])) {
$questions[$detailsStudentId] = array(
'studentalias' => $detailsStudentAlias,
'studentforename' => $detailsStudentForename,
'studentsurname' => $detailsStudentSurname,
'questions' => array()
);
}
$questions[$detailsStudentId]['questions'][$detailsQuestionId] = array(
'questionno'=>$detailsQuestionNo,
'content'=>$detailsQuestionContent,
'optiontype'=>$detailsOptionType,
'noofanswers'=>$detailsNoofAnswers,
'answer'=>$detailsAnswer,
'replytype'=>$detailsReplyType,
'questionmarks'=>$detailsQuestionMarks,
'studentanswer'=>$detailsStudentAnswer,
'responsetime'=>$detailsResponseTime,
'mouseclick'=>$detailsMouseClick,
'studentmark'=>$detailsStudentMark
);
}
$selectedstudentanswerstmt->close();
foreach ($questions as $studentId => $studentData) {
echo '<p>'.$studentData['studentalias'].' - '.$studentData['studentforename'].' '.$studentData['studentsurname'].'</p>';
foreach ($studentData['questions'] as $questionId => $questionData) {
echo '<p><strong>'.$questionData['questionno'].': '.$questionData['content'].'<br/>';
echo $questionData['optiontype'].' - '.$questionData['noofanswers'].' - '.$questionData['answer'].' - '.$questionData['replytype'].' - '.$questionData['questionmarks'].'<br/>';
echo $questionData['studentanswer'].' - '.$questionData['responsetime'].' - '.$questionData['mouseclick'].' - '.$questionData['studentmark'].'</strong></p>';
}
}
Below are the possible var_dumps for $_POST['student'] and $_POST['question']:
SINGLE STUDENT AND SINGLE QUESTION:
- Student: Chris Tucker – string(2) “40”
- Question: 1 – string(2) “72”
SINGLE STUDENT AND ALL QUESTIONS:
- Student: Chris Tucker – string(2) “40”
- Question: All – string(1) “0”
ALL STUDENTS AND SINGLE QUESTION:
- Student: All – string(1) “0”
- Question: 1 – string(1) “72”
ALL STUDENTS AND ALL QUESTIONS:
- Student: All – string(1) “0”
- Question: All – string(1) “0”
Below is example var_dump($questions); if I select All students and All questions:
array(1) {
[39]=> array(4) {
["studentalias"]=> string(8) "u4838229"
["studentforename"]=> string(5) "Chris"
["studentsurname"]=> string(6) "Tucker"
["questions"]=> array(1) {
[72]=> array(11) {
["questionno"]=> int(1)
["content"]=> string(14) "What is a RAM?"
["optiontype"]=> string(3) "A-E"
["noofanswers"]=> int(1)
["answer"]=> string(7) "B,C,D,E"
["replytype"]=> string(6) "Single"
["questionmarks"]=> int(5)
["studentanswer"]=> string(9) "A,B,C,D,E"
["responsetime"]=> string(8) "00:00:07"
["mouseclick"]=> int(1)
["studentmark"]=> string(1) "2" } } } }
UPDATE:
If I keep the mysqli query using a static WHERE clause when it just checks for q.SessionId = ? only, then when I select the All options in etiher or both drop down menus, it outputs the results fine no problem, only wither the dynamic where clause which I need to include as user my be able to select an indivdual student and/or indivdiual question that the All options do not work properly. Below is working mysqli code when using static WHERE clause:
$selectedstudentanswerqry = "
SELECT
sa.StudentId, StudentAlias, StudentForename, StudentSurname, q.SessionId,
q.QuestionId, QuestionNo, QuestionContent, o.OptionType, q.NoofAnswers,
GROUP_CONCAT( DISTINCT Answer ORDER BY Answer SEPARATOR ',' ) AS Answer, r.ReplyType, QuestionMarks,
GROUP_CONCAT(DISTINCT StudentAnswer ORDER BY StudentAnswer SEPARATOR ',') AS StudentAnswer, ResponseTime, MouseClick,
(
SELECT sum( StudentMark )
FROM Student_Answer sta
WHERE sa.StudentId = sta.StudentId
AND sa.QuestionId = sta.QuestionId
)StudentMark
FROM Student st
INNER JOIN Student_Answer sa ON (st.StudentId = sa.StudentId)
INNER JOIN Student_Response sr ON (sa.StudentId = sr.StudentId) AND sa.QuestionId = sr.QuestionId
INNER JOIN Question q ON (sa.QuestionId = q.QuestionId)
INNER JOIN Answer an ON q.QuestionId = an.QuestionId
LEFT JOIN Reply r ON q.ReplyId = r.ReplyId
LEFT JOIN Option_Table o ON q.OptionId = o.OptionId
LEFT JOIN Session_Taken sta ON (st.StudentId = sta.StudentId)
WHERE q.SessionId = ?
GROUP BY sa.StudentId, q.QuestionId
ORDER BY StudentAlias, q.SessionId, QuestionNo
";
global $mysqli;
$selectedstudentanswerstmt=$mysqli->prepare($selectedstudentanswerqry);
$selectedstudentanswerstmt->bind_param('i',$_POST['session']);
// get result and assign variables (prefix with db)
$selectedstudentanswerstmt->execute();
$selectedstudentanswerstmt->bind_result($detailsStudentId,$detailsStudentAlias,$detailsStudentForename,$detailsStudentSurname,$detailsSessionId,
$detailsQuestionId,$detailsQuestionNo,$detailsQuestionContent,$detailsOptionType,$detailsNoofAnswers,$detailsAnswer,$detailsReplyType,$detailsQuestionMarks,
$detailsStudentAnswer,$detailsResponseTime,$detailsMouseClick,$detailsStudentMark);
The empty() considers a ‘0’ as empty http://php.net/manual/en/function.empty.php,
so in
$p_student = empty($_POST["student"])?'':$_POST["student"];$p_student is true when $_POST[“student”] is ‘0’… As a result, the case below is always ‘default’, so you should may be set $p_student as a ‘0’ if empty() and it should be ok…I think… ( Thats for both $p_student and $p_question of course…).`