0

ユーザーがドロップダウンメニューを使用して、表示したい学生や質問をフィルタリングできる2つのドロップダウンメニューがあります。可能なフィルターのタイプは次のとおりです。

  • すべての生徒とすべての質問を選択
  • すべての生徒と 1 つの質問を選択
  • すべての質問と 1 人の生徒を選択
  • 1 人の生徒と 1 つの質問を選択

以下はドロップダウンメニューです。

<p>
    <strong>Student:</strong>
    <select name="student" id="studentsDrop">
    <option value="All">All</option>
    <?php
    while ( $currentstudentstmt->fetch() ) {
    $stu = $dbStudentId;
    if(isset($_POST["student"]) && $stu == $_POST["student"]) 
        echo "<option selected='selected' value='$stu'>" . $dbStudentAlias . " - " . $dbStudentForename . " " . $dbStudentSurname . "</option>" . PHP_EOL;
    else
        echo "<option value='$stu'>" . $dbStudentAlias . " - " . $dbStudentForename . " " . $dbStudentSurname . "</option>" . PHP_EOL;
    }
    ?>
    </select>
    </p>

    <p>
    <strong>Question:</strong>
    <select name="question" id="questionsDrop">
    <option value="All">All</option>
    <?php
    while ( $questionsstmt->fetch() ) {
    $ques = $dbQuestionId;
    if(isset($_POST["question"]) && $ques == $_POST["question"]) 
        echo "<option selected='selected' value='$ques'>" . $dbQuestionNo . "</option>" . PHP_EOL;
    else
        echo "<option value='$ques'>" . $dbQuestionNo . "</option>" . PHP_EOL;
    }
    ?>
    </select>

</p>

ここで、ドロップダウン メニューから選択した生徒と質問を決定する mysqli クエリを設定します。

私の質問は、ドロップダウンメニューから言及した4つの可能性をチェックする4つのクエリを設定する必要があるか、それとももっと短い方法がありますか?

使用する必要がありますか:

 if ($_POST['question'] == 'All' && if ($_POST['student'] == 'All'){){

//NO WHERE CLAUSE

    if ($_POST['question'] == 'All' && if ($_POST['student'] != 'All'){){

//WHERE CLAUSE FOR FINDING SELECTED STUDENT

    if ($_POST['question'] != 'All' && if ($_POST['student'] == 'All'){){

//WHERE CLAUSE FOR FINDING SELECTED QUESTION 

    if ($_POST['question'] != 'All' && if ($_POST['student'] != 'All'){){

//WHERE CLAUSE FOR FINDING SELECTED QUESTION AND SELECTED STUDENT

アップデート:

私が今持っているもの:

    function AssessmentIsSubbmitted()
{
    if(isset($_POST['answerSubmit'])) // we have subbmited the first form
    {

//QUERY 1: Student details depending on selected student(s)

if ($_POST['student'] == 'All'){

$selectedstudentqry = "
SELECT
StudentAlias, StudentForename, StudentSurname
FROM Student s
INNER JOIN Student_Session ss ON s.StudentId = ss.StudentId
WHERE SessionId = ?
ORDER BY StudentAlias
";

global $mysqli;
$selectedstudentstmt=$mysqli->prepare($selectedstudentqry);
// You only need to call bind_param once
$selectedstudentstmt->bind_param("i",$_POST["session"]);
// get result and assign variables (prefix with db)
$selectedstudentstmt->execute(); 
$selectedstudentstmt->bind_result($detailsStudentAlias,$detailsStudentForename,$detailsStudentSurname);
$selectedstudentstmt->store_result();
$selectedstudentnum = $selectedstudentstmt->num_rows();     

}else{  

$selectedstudentqry = "
SELECT
StudentAlias, StudentForename, StudentSurname
FROM
Student
WHERE
(StudentId = ?)
ORDER BY StudentAlias
";

global $mysqli;
$selectedstudentstmt=$mysqli->prepare($selectedstudentqry);
// You only need to call bind_param once
$selectedstudentstmt->bind_param("i",$_POST["student"]);
// get result and assign variables (prefix with db)
$selectedstudentstmt->execute(); 
$selectedstudentstmt->bind_result($detailsStudentAlias,$detailsStudentForename,$detailsStudentSurname);
$selectedstudentstmt->store_result();
$selectedstudentnum = $selectedstudentstmt->num_rows();    

}    


//QUERY 2: Question details depending on selected question(s)


if ($_POST['question'] == 'All'){

$selectedquestionqry = " SELECT q.QuestionNo, q.QuestionContent, o.OptionType, q.NoofAnswers, GROUP_CONCAT( DISTINCT Answer
                    ORDER BY Answer
                    SEPARATOR ',' ) AS Answer, r.ReplyType, q.QuestionMarks
                    FROM Question q
                    LEFT 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
                    WHERE SessionId = ?
                    GROUP BY q.QuestionId
                    ORDER BY q.QuestionId";
";

global $mysqli;
$selectedquestionstmt=$mysqli->prepare($selectedquestionqry);
// You only need to call bind_param once
$selectedstudentstmt->bind_param("i",$_POST["session"]);
// get result and assign variables (prefix with db)
$selectedquestionstmt->execute(); 
$selectedquestionstmt->bind_result($detailsQuestionNo,$detailsQuestionContent,$detailsOptionType,$detailsNoofAnswers,
$detailsAnswer,$detailsReplyType,$detailsQuestionMarks);
$selectedquestionstmt->store_result();
$selectedquestionnum = $selectedquestionstmt->num_rows(); 


}else{

$selectedquestionqry = "
SELECT q.QuestionNo, q.QuestionContent, o.OptionType, q.NoofAnswers, GROUP_CONCAT( DISTINCT Answer
                    ORDER BY Answer
                    SEPARATOR ',' ) AS Answer, r.ReplyType, q.QuestionMarks
                    FROM Question q
                    LEFT 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
                    WHERE QuestionId = ?
                    GROUP BY q.QuestionId
                    ORDER BY q.QuestionId
";

global $mysqli;
$selectedquestionstmt=$mysqli->prepare($selectedquestionqry);
// You only need to call bind_param once
$selectedquestionstmt->bind_param("i",$_POST["question"]);
// get result and assign variables (prefix with db)
$selectedquestionstmt->execute(); 
$selectedquestionstmt->bind_result($detailsQuestionNo,$detailsQuestionContent,$detailsOptionType,$detailsNoofAnswers,
$detailsAnswer,$detailsReplyType,$detailsQuestionMarks);
$selectedquestionstmt->store_result();
$selectedquestionnum = $selectedquestionstmt->num_rows(); 

}

//QUERY 3: Student Answers depending on selected student(s) and selected question(s)

$studentanswerqry = "
SELECT
sa.StudentId, sa.QuestionId, GROUP_CONCAT(DISTINCT StudentAnswer ORDER BY StudentAnswer SEPARATOR ',') AS StudentAnswer, ResponseTime, MouseClick, StudentMark
FROM Student_Answer sa
INNER JOIN Student_Response sr ON sa.StudentId = sr.StudentId
WHERE
(sa.StudentId = ? AND sa.QuestionId = ?)
GROUP BY sa.StudentId, sa.QuestionId
";

global $mysqli;
$studentanswerstmt=$mysqli->prepare($studentanswerqry);
// You only need to call bind_param once
$studentanswerstmt->bind_param("ii",$_POST["student"], $_POST["question"]);
// get result and assign variables (prefix with db)
$studentanswerstmt->execute(); 
$studentanswerstmt->bind_result($detailsStudentAnswer,$detailsResponseTime,$detailsMouseClick,$detailsStudentMark);
$studentanswerstmt->store_result();
$studentanswernum = $studentanswerstmt->num_rows(); 


}

?>
4

3 に答える 3

3

WHERE句を繰り返し作成できます。句が明示的なフィルタリングを行うことを考慮してください。そのWHEREため、何かの「すべて」を選択している場合は、フィルターを追加する必要はありません。他のフィルターは相互に構築されるため、単純にANDs でそれらを結合できWHEREます。

$query = 'SELECT ... FROM ...';

// Initially empty
$where = array();
$parameters = array();

// Check whether a specific student was selected
if($stu !== 'All') {
    $where[] = 'stu = ?';
    $parameters[] = $stu;
}

// Check whether a specific question was selected
// NB: This is not an else if!
if($ques !== 'All') {
    $where[] = 'ques = ?';
    $parameters[] = $ques;
}

// If we added to $where in any of the conditionals, we need a WHERE clause in
// our query
if(!empty($where)) {
    $query .= ' WHERE ' . implode(' AND ', $where);
}

$result = prepare_and_execute_query($query, $parameters);

さて、あなたの更新を見ると、かなり複雑な一連のクエリがありますが、それを 1 つのステートメントに結合することができます。これを試してください:

SELECT
    s.StudentId, s.StudentAlias, s.StudentForename,         -- Student fields
    s.StudentSurname,
    q.QuestionId, q.QuestionNo, q.QuestionContent,          -- Question fields
    q.OptionType, q.NoofAnswers, q.Answer, q.ReplyType,
    q.QuestionMarks,
    GROUP_CONCAT(DISTINCT sa.StudentAnswer ORDER BY         -- Answer fields
        sa.StudentAnswer SEPARATOR ',') AS StudentAnswer,
    sr.ResponseTime, sr.MouseClick, sr.StudentMark
FROM Student s
INNER JOIN Student_Answer sa ON (s.StudentId = sa.StudentId)
INNER JOIN Question q ON (sa.QuestionId = q.QuestionId)
INNER JOIN Student_Response sr ON (sa.StudentId = sr.StudentId)
WHERE                     -- This WHERE clause may be entirely removed, 
                          -- depending on the filters
    s.StudentId = ? AND   -- This is removed if $_POST['student'] is 'All'
    q.QuestionId = ?      -- This is removed if $_POST['question'] is 'All'
GROUP BY sa.StudentId, q.QuestionId

これはあなたが望むことをすると思います。Student_Responseどのフィールドが の一部で、どのフィールドが の一部なのかよくわからなかったStudent_Answerので、SELECT.


残念ながら、そのアプローチはユースケースでは機能しません。ただし、私が提案した元のロジックが、指定されたクエリの 1 つとどのように機能するかを検討することはできます。

$selectedstudentqry = "
SELECT
StudentAlias, StudentForename, StudentSurname
FROM
Student ";
if($_POST['student'] !== 'All') { // Check here
    $selectedstudentqry .= "
    WHERE
    (StudentId = ?) ";
}
$selectedstudentqry .= "
ORDER BY StudentAlias
";

global $mysqli;
$selectedstudentstmt=$mysqli->prepare($selectedstudentqry);
if($_POST['student'] !== 'All') {
    // You only need to call bind_param once
    $selectedstudentstmt->bind_param("i",$_POST["student"]);
}
// get result and assign variables (prefix with db)
$selectedstudentstmt->execute(); 
$selectedstudentstmt->bind_result($detailsStudentAlias,$detailsStudentForename,$detailsStudentSurname);
$selectedstudentstmt->store_result();
$selectedstudentnum = $selectedstudentstmt->num_rows();

ifコードの重複を減らすために、外側の s をコード内のより具体的な場所に移動したことに注目してください。あなたのような重複が見られる場合は、条件を広くしすぎるなどのことをしている可能性が非常に高いです。ただし、これを単純化して冗長性を減らすことは間違いなく正しい方向に進んでいます。

于 2013-01-26T03:06:41.793 に答える
0

これは、ユーザー入力の 64 の順列がある場合に使用したコードです。別のページからのライダー ID、姓名の一部、年、月、またはコース ID が含まれる場合があります。

さまざまな AND、IS LIKE などを使用して where 句の一部を構成します。

$params = array();
$types = "";


if ( isset($_GET["riderid"]) && $_GET["riderid"] )  {
    $where = sprintf (' AND %s.id = ?', $tables["rider"]);
    $params[]= $_GET["riderid"];
    $types = $types .'i';

} else {
    if ( isset($_GET["last"]) && $_GET["last"] ) {

        $where = sprintf(' AND %s.last like ?', $tables["rider"]);
        $params[] = $_GET["last"] . "%";
        $types = $types . "s";
    }

    if ( isset($_GET["first"]) && $_GET["first"] ) {

        $whereFirst = sprintf(' AND %s.first like ?', $tables["rider"]);
        $where = $where . $whereFirst;
        $params[] = $_GET["first"] . "%";
        $types = $types . "s";
    }
}

if ( isset($_GET["year"]) && $_GET["year"] && $_GET["year"] != -1 )  {
    $whereYear = sprintf(' AND YEAR(%s.date) = ?', $tables["race"]);
    $where = $where . $whereYear;
    $params[] = $_GET["year"];
    $types = $types . "i";
}

if ( isset($_GET["month"]) && $_GET["month"] && $_GET["month"] != -1 )  {
    $whereMonth = sprintf(' AND month(%s.date) = ?', $tables["race"]);
    $where = $where . $whereMonth;
    $params[] = $_GET["month"];
    $types = $types . "i";

}  

if ( isset($_GET["courseid"]) && $_GET["courseid"] && $_GET["courseid"] != -1 ) {
    $whereCourse = sprintf(' AND %s.courseid = ?', $tables["race"]);
    $where = $where . $whereCourse;
    $params[] = $_GET["courseid"];
    $types = $types . "i";
}

これがクエリです。

    //
    // Show selected races
    //
    $listQuery = "SELECT {$tables["race"]}.raceid, {$tables["race"]}.typeid, " .
             "           tag,  {$tables["race"]}.date, " .
             "           {$tables["location"]}.name, {$tables["course"]}.dist, " .
             "           {$tables["course"]}.description,  " .
             "           {$tables["result"]}.time, {$tables["result"]}.dnf, " .
             "           {$tables["rider"]}.first, {$tables["rider"]}.last ".
             "  FROM {$tables["race"]}, {$tables["sysracetype"]}, " .
             "       {$tables["course"]}, {$tables["location"]}, " .
             "       {$tables["result"]}, {$tables["rider"]} " .
             " WHERE {$tables["race"]}.courseid = {$tables["course"]}.courseid " .
             "   AND {$tables["race"]}.typeid = {$tables["sysracetype"]}.typeid " .
             "   AND {$tables["course"]}.locid = {$tables["location"]}.locid " .
             "   AND {$tables["race"]}.raceid = {$tables["result"]}.raceid" .
             "   AND {$tables["result"]}.riderid = {$tables["rider"]}.id" .
             $where .
             $orderby;

パラメータを準備してバインドします。

$stmt = mysqli_prepare ($db_connection, $listQuery);
// 
// Handle the varying number of SQL parameters / place holders.
// Push the first two parameter of mysqli_stmt_bind_param
//
$bindArgs = array ($stmt, $types);

//
// Change parameters to refs  (depends on PHP version)   
//
foreach ($params as $key => $value)  
    $bindArgs[] =& $params[$key];

//
// Use "call back" to pass all params.
//
call_user_func_array("mysqli_stmt_bind_param", $bindArgs);
于 2016-03-07T15:44:44.903 に答える
-1

この方法で同様の問題を解決しました。ここで、$parmMap は 2 のべき乗 (1,2) で構築されます。これは、オプションの WHERE 句の各項目を検出し、適切な AND fieldName = ? を追加するためです。

switch ($parmMap ) {
    case 0:
      break;
    case 1:
      mysqli_stmt_bind_param ($stmt, "i", $courseParm );
      break;
    case 2:
      mysqli_stmt_bind_param ($stmt, "i", $yearParm );
      break;
    case 3:
      mysqli_stmt_bind_param ($stmt, "ii", $courseParm, $yearParm );
      break;
    default:
      break;
}

ただし、6 つのオプションの where 句条件を持つ別のクエリには、これを使用しません。発見しましたcall_user_func_array

于 2016-03-05T19:21:58.070 に答える