【问题标题】:How to create a mysqli dynamic WHERE clause如何创建 mysqli 动态 WHERE 子句
【发布时间】:2013-01-27 00:20:22
【问题描述】:

我在这里有一个应用程序:Application

该应用程序在那里向您显示我想用作过滤器的两个下拉菜单,以便能够获得学生的答案,确定所选学生和从相应下拉菜单中选择的问题.

要查看下拉菜单,请在应用程序中从Assessment 下拉菜单中选择Assessment 并提交,您将看到学生和问题下拉菜单显示在下方。

现在我要做的是创建一个动态的 WHERE 子句,这取决于用户单击Get Student Answers 按钮时从学生和问题下拉菜单中选择的选项。

以下是当前查询。查询必须在 WHERE 子句中始终具有默认子句 SessionId = ?。其他子句studentId = ?questionId = ?取决于用户的选项 已从两个下拉菜单中进行选择。

$selectedstudentanswerqry = "
SELECT
StudentAlias, q.SessionId, QuestionNo, QuestionContent, o.OptionType, GROUP_CONCAT( DISTINCT Answer
ORDER BY Answer SEPARATOR ',' ) AS Answer, r.ReplyType, 
GROUP_CONCAT(DISTINCT StudentAnswer ORDER BY StudentAnswer SEPARATOR ',') AS StudentAnswer, ResponseTime
FROM Student s
INNER JOIN Student_Answer sa ON (s.StudentId = sa.StudentId)
INNER JOIN Student_Response sr ON (sa.StudentId = sr.StudentId)
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
WHERE (SessionId = ?)
GROUP BY sa.StudentId, q.QuestionId
ORDER BY StudentAlias, q.SessionId, QuestionNo
";

global $mysqli;
$selectedstudentanswerstmt=$mysqli->prepare($selectedstudentanswerqry);
// You only need to call bind_param once
$selectedstudentanswerstmt->bind_param("i",$_POST["session"]);
// get result and assign variables (prefix with db)
$selectedstudentanswerstmt->execute(); 
$selectedstudentanswerstmt->bind_result($detailsStudentAlias,$detailsSessionId,$detailsQuestionNo, 
$detailsQuestonContent,$detailsOptionType,$detailsAnswer,$detailsReplyType,$detailsStudentAnswer,$detailsResponseTime);
$selectedstudentanswerstmt->store_result();
$selectedstudentanswernum = $selectedstudentanswerstmt->num_rows(); 

以下是学生和问题下拉菜单作为示例 html:

学生下拉菜单:

<select name="student" id="studentsDrop">
<option value="All">All</option>
<option value="3">u0499220 - Jack Briggs</option>
<option value="7">u0093220 - Mary Kay</option>
</form>

问题下拉菜单:

<select name="question" id="questionsDrop">
<option value="All">All</option>
<option value="34">1</option>
<option value="35">2</option>
<option value="36">3</option>
</form>

我在想,如果选择了特定的学生,则在 WHERE 子句中包含 StudentId = ?,如果选择了特定的问题编号,则在 WHERE 子句中包含 QuestionId = ?。但是,如果在 Student 下拉菜单中选择了 All 值,则从 WHERE 子句中删除 StudentId = ?,因为我们正在查找所有学生,而不是针对特定学生进行缩减。如果从“问题”下拉菜单中选择了 All 值,但显然是在处理 QuestionId = ?

【问题讨论】:

标签: php html mysqli


【解决方案1】:

你知道你可以在这里写一个子查询吗?

WHERE (SessionId = ?)

喜欢

WHERE SessionId IN(SELECT SessionId FROM ...)

http://dev.mysql.com/tech-resources/articles/subqueries_part_1.html

【讨论】:

  • 我真的需要子查询吗?我用我拥有的东西测试了我的查询,并手动添加了 StudentId 和 QuestionId 的 where 子句,并将其设置为示例 ID,它们运行良好。我的问题只是根据选择的选项创建一个动态的 where 子句。如果您可以扩展代码以显示您要实现的目标,那么我将更容易理解您在说什么。但是如果可以使用动态 where 子句来完成会很好,因为我已经在使用 JOINS 来连接表
  • 也许可以稍微修改一下情况以使用 CASE 语句。 dev.mysql.com/doc/refman/5.0/en/case.html
  • 那么关于两个下拉菜单之间所有可能性的 case 语句并显示每个 case 的 WHERE 子句?这是最好的方法吗?如果您认为是这样,请提供一个示例,说明您将如何编写案例陈述。不必写完整的案例陈述,但想看看如何从下拉菜单中列出可能性
【解决方案2】:

好吧,你知道吗?我想我在这里误解了真正的问题。您可能会发现这样做效果更好:

    $selectedstudentanswerqry = "
    SELECT
    StudentAlias, q.SessionId, QuestionNo, QuestionContent, o.OptionType, GROUP_CONCAT( DISTINCT Answer
    ORDER BY Answer SEPARATOR ',' ) AS Answer, r.ReplyType, 
    GROUP_CONCAT(DISTINCT StudentAnswer ORDER BY StudentAnswer SEPARATOR ',') AS StudentAnswer, ResponseTime
    FROM Student s
    INNER JOIN Student_Answer sa ON (s.StudentId = sa.StudentId)
    INNER JOIN Student_Response sr ON (sa.StudentId = sr.StudentId)
    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";

    if (studentId = something && questionId = something) {

    $selectedstudentanswerqry .= "WHERE (SessionId = ?)
    GROUP BY sa.StudentId, q.QuestionId
    ORDER BY StudentAlias, q.SessionId, QuestionNo
    ";

    } else if (studentId = somethingelse && questionId = somethingelse) {

    $selectedstudentanswerqry .= "WHERE (SessionId = ?)
    GROUP BY sa.StudentId, q.QuestionId
    ORDER BY StudentAlias, q.SessionId, QuestionNo
    ";

    } else {
    $selectedstudentanswerqry .= "WHERE (SessionId = ?)
    GROUP BY sa.StudentId, q.QuestionId
    ORDER BY StudentAlias, q.SessionId, QuestionNo
    ";
    }

【讨论】:

  • 我将不得不走这条路。幸运的是,我只有 2 个下拉菜单,所以我可以使用它。但是在我标记你的答案之前,只要给我评论一下如果有 5 或 6 个下拉菜单的编码方式,你会使用 case 语句并检查所有 5 - 6 个选项吗?这就是为什么我要问最好的方法,因为我喜欢一个实用的解决方案,无论是有 2 个下拉菜单还是 6 个下拉菜单,它都可以工作,这是为了帮助其他可能看到这个问题的人
  • 实际上,是的,case 语句是等价的。我编辑了上面的答案,以表明最后您可以使用“else”子句结束,但是,如果您使用 case 语句,您将拥有“default”子句。
  • 我仍然认为在 where 子句中可能有一个优雅的解决方案,可以使用嵌套的 select 或 case 语句。由于这个想法对我来说有点复杂,而且我没有完整的表结构,我建议了一种允许更多动态交互的 php 方式。不幸的是,MySQL 是一个不太动态的世界,编写查询有时会非常复杂。
  • 我不介意使用 php 结构,但我需要你能够编写它,因为我以前从未这样做过。如果我能够向您展示表格结构,您认为您能够做到吗?
猜你喜欢
  • 2011-01-31
  • 2011-08-28
  • 1970-01-01
  • 2013-05-11
  • 1970-01-01
  • 2013-01-13
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
相关资源
最近更新 更多