All
関連するドロップダウンメニューの一方または両方でオプションを選択するときに、データをループするのに問題があります。すべてのレコードを調べて表示するのではなく、1セットのデータを通過するだけです。各生徒と参加した各質問の詳細を表示することを想定しています。ただし、表示されているのは1人の生徒と1つの質問だけであり、それだけです。
表示される内容は次のとおりです。
しかし、代わりに、現時点ではこれを表示しているだけです。
この問題の原因は、私が設定した動的なWHERE句であると思います。以下は、動的WHERE句のしくみです。
- 強制的なWHERE条件
q.SessionId = ?
- ユーザーが学生のドロップダウンメニューから1人の学生を選択した場合は、
AND sa.StudentId = ?
WHERE句に追加します - ユーザーが
All
学生のドロップダウンメニューから学生のオプションを選択した場合はAND sa.StudentId = ?
、WHERE句から削除するか表示しない - ユーザーが質問のドロップダウンメニューから単一の質問を選択した場合は、
AND q.QuestionId = ?
WHERE句に追加します - ユーザーが
All
質問ドロップダウンメニューから質問オプションを選択した場合はAND q.QuestionId = ?
、WHERE句から削除するか表示しない
私は3つのドロップダウンメニューを持っています(以下はサンプルデータでどのように見えるかです):
セッション:
<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
。
1人の生徒と1つの質問を選択すると、詳細が正しく表示されます。
- 学生: Luke McFadzen-ドロップダウン値:39
- 質問: 1-ドロップダウン値:72
したがって、WHERE条件はq.SessionId = 26 AND sa.StudentId = 39 AND q.QuestionId = 72
です。
しかし、All
学生と質問のドロップダウンメニューのいずれかまたは両方でオプションを選択すると、出力には1人の学生と1つの質問のみが表示され、奇妙な理由で、すべての質問からの回答が結合され、すべての学生の回答が1つの出力に結合されます。
両方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 = ?
を選択すると詳細が正しく出力されますが、ドロップダウンメニューから選択したすべての異なるオプションに対してクエリが機能する必要があるため、動的なWHEREが必要な理由句。正しい詳細が出力されるようにするにはどうすればよいですか?All
All
コード:
$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']
およびの可能なvar_dumps$_POST['question']
です。
単一の学生と単一の質問:
- 学生:クリス・タッカー-string(2) "40"
- 質問:1-string(2) "72"
一人の学生とすべての質問:
- 学生:クリス・タッカー-string(2) "40"
- 質問:すべて-string(1) "0"
すべての学生と単一の質問:
- 学生:すべて-string(1) "0"
- 質問:1-string(1) "72"
すべての学生とすべての質問:
- 学生:すべて-string(1) "0"
- 質問:すべて-string(1) "0"
以下は、生徒と質問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);