在一个或两个相关下拉菜单中选择All
选项时,我无法循环浏览数据。它不是通过所有记录并显示它们,而是仅通过一组数据。它假设显示每个学生和他们参与的每个问题的详细信息。但它只显示一个学生和一个问题,这就是全部。
以下是它应显示的内容:
但目前只是展示了这个:
我相信造成这个问题的原因是我设置的动态WHERE子句。下面是动态WHERE子句的工作原理:
q.SessionId = ?
AND sa.StudentId = ?
添加到WHERE子句All
学生选项,则从WHERE子句中删除或不显示AND sa.StudentId = ?
AND q.QuestionId = ?
添加到WHERE子句All
问题选项,则从WHERE子句中删除或不显示AND q.QuestionId = ?
我有三个下拉菜单(下面是样本数据的样子):
会话
<select name="session" id="sessionsDrop">
<option value="26">POKUB1</option>
<option value="27">POKUB2</option>
</select>
学生:
<select name="student" id="studentsDrop">
<option value="0">All</option>
<option value="39">Luke Mcfadzen</option>
<option value="40">Chris Tucker</option>
</select>
问题:
<select name="question" id="questionsDrop">
<option value="0">All</option>
<option value="72">1</option>
<option value="73">2</option>
</select>
不要忘记我在上面提到的WHERE条件是如何工作的。让我们说从会话下拉菜单中选择的会话是POKUB 1, drop down value: 26
。
如果您选择单个学生和单个问题,则会正确显示详细信息,例如
所以WHERE条件是q.SessionId = 26 AND sa.StudentId = 39 AND q.QuestionId = 72
。
但是如果我在学生和问题下拉菜单中选择一个All
选项,那么输出只会显示一个学生和一个问题,并且由于一些奇怪的原因,它结合了所有问题的答案并组合了所有学生回答单个输出的答案。
现在两个下拉菜单中的All
选项的下拉值都为0
,现在0
不是从数据库中选择的值,但我们在动态where子句中声明了如果从特定下拉菜单中选择0
值,则从WHERE子句中删除相关条件,例如:
All
名学生和单个问题(价值72
) - WHERE q.SessionId
= 26 AND q.QuestionId = 72
39
)学生和All
个问题 - WHERE q.SessionId
= 26 AND sa.StudentId = 39
All
学生和All
个问题 - WHERE q.SessionId = 26
上面的情景有问题
如果我只是使用静态WHERE子句WHERE q.SessionId = ?
离开查询,那么如果我选择All
学生和All
问题,它会正确输出详细信息,但我需要查询才能工作从下拉菜单中选择所有不同的可能选项,因此我需要一个动态WHERE子句。如何让它工作,以便输出正确的细节?
代码:
$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>';
}
}
以下是$_POST['student']
和$_POST['question']
的可能var_dumps:
单身学生和单一问题:
单身学生和所有问题:
所有学生和单个问题:
所有学生和所有问题:
如果我选择var_dump($questions);
个学生和All
个问题,则下面是示例All
:
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" } } } }
更新
如果我在仅检查q.SessionId = ?
时使用静态WHERE子句保留mysqli查询,那么当我在etiher或两个下拉菜单中选择All
选项时,它会输出结果很好没问题,只有我需要包含的动态where子句作为用户我能够选择一个单独的学生和/或All
选项不能正常工作的个人问题。下面是使用静态WHERE子句时的mysqli代码:
$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);
答案 0 :(得分:1)
我相信你问题的根源是:
// 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';
}
将学生添加到where子句的代码只执行一次,并且不支持多个学生被选中。
这样的事情应该有用,假设您修改代码以从表单传递学生ID数组:
if (!empty($_POST['student'])) {
$students = filter_input_array(INPUT_POST, 'student', FILTER_SANITIZE_NUMBER_INT);
if ($students !== false) {
$num_students = count($students);
$where[] = 'sa.StudentId IN (' . rtrim(str_repeat('?,', $num_students), ',') . ')';
$parameters = array_merge($parameters, $students);
}
}
一些事情:
[]
添加到表单字段的名称(即:<select name="student[]">
PHP会将其解释为$ _POST中的数组。$questions
将保留所有这些结果。答案 1 :(得分:1)
empty()将'0'视为空http://php.net/manual/en/function.empty.php,
所以在$p_student = empty($_POST["student"])?'':$_POST["student"];
$ p_student是真的,当$ _POST [“student”]为'0'时...结果,下面的情况总是'默认',所以你应该将$ p_student设置为'' 0'如果为空()它应该没问题......我想...(这当然是$ p_student和$ p_question ......)。
`
$p_student = empty($_POST["student"])?0:$_POST["student"]; // Now if $_POST['student'] is either 0 or empty $p_student will be 0
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"])?0:$_POST["question"]; // Same here, if $_POST['question'] is either 0 or empty $p_question will be 0
switch($p_question){
case 0:
//dont' add where filters
break;
default:
$where[] = 'q.QuestionId = ?';
$parameters[] .= $_POST["question"];
$parameterTypes .= 'i';
}`
答案 2 :(得分:0)
我认为你错过了
之后的结束}// You only need to call bind_param once
现在你的
if(!empty($where)) {
不会以它应该结束的地方结束......