我有2个下拉菜单,用户可以使用下拉菜单过滤他们希望看到的学生和问题。可能的过滤器类型是:
下面是下拉菜单:
<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();
}
?>
答案 0 :(得分:3)
您可以迭代地构建WHERE
子句。考虑WHERE
子句进行显式过滤,因此对于您选择“全部”某些内容的情况,您不需要添加任何过滤器。其他过滤器相互构建,因此我们只需将其与AND
中的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);
好的,所以查看您的更新,您有一组相当复杂的查询,但可以将它组合成一个语句。试一试:
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
中的列。
不幸的是,这种方法对您的用例不起作用。但我们仍然可以考虑我提出的原始逻辑如何与您给出的一个查询一起工作:
$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
移动到代码中更具体的位置以减少代码重复。如果你看到像你一样的重复,那么你很有可能会做出像你的条件太宽泛一样的事情。尽管如此,你肯定在努力简化这一过程并减少冗余。
答案 1 :(得分: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);
答案 2 :(得分:-1)
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;
}
我不会将此用于另一个具有六个可选where子句条件的查询!我发现了call_user_func_array
。