All在一个或两个相关下拉菜单中选择一个选项时,我在循环数据时遇到问题。它不会遍历所有记录并显示它们,它只是通过一组数据。假设显示每个学生和他们参与的每个问题的详细信息。但它只显示一个学生和一个问题,仅此而已。
下面是它应该显示的内容:

但目前它只是显示这个:

我相信导致这个问题的原因是我设置的动态 WHERE 子句。以下是动态 WHERE 子句的工作原理:
- 强制 WHERE 条件
q.SessionId = ? - 如果用户从学生下拉菜单中选择单个学生,则添加
AND sa.StudentId = ?到 WHERE 子句 - 如果用户  
All从学生下拉菜单中选择学生选项,AND sa.StudentId = ?则从 WHERE 子句中删除或不显示 - 如果用户从问题下拉菜单中选择单个问题,则添加
AND q.QuestionId = ?到 WHERE 子句 - 如果用户  
All从问题下拉菜单中选择问题选项,AND q.QuestionId = ?则从 WHERE 子句中删除或不显示 
我有三个下拉菜单(下面是示例数据的样子):
会议:
<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.
如果您选择一个学生和一个问题,那么它会正确显示详细信息,例如
- 学生: Luke McFadzen - 下拉值:39
 - 问题: 1 - 下拉值:72
 
所以 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']var_dumps $_POST['question']:
单个学生和单个问题:
- 学生:Chris Tucker - string(2) "40"
 - 问题:1 - 字符串(2)“72”
 
单身学生和所有问题:
- 学生:Chris Tucker - string(2) "40"
 - 问题:全部 - 字符串(1)“0”
 
所有学生和一个问题:
- 学生:全部 - 字符串(1)“0”
 - 问题:1 - 字符串(1)“72”
 
所有学生和所有问题:
- 学生:全部 - 字符串(1)“0”
 - 问题:全部 - 字符串(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" } } } }
更新:
如果我仅在仅检查时使用静态 WHERE 子句保留 mysqli 查询q.SessionId = ?,那么当我All在 etiher 或两个下拉菜单中选择选项时,它输出结果没问题,只会枯萎我需要的动态 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);