1

我已经写SELECT了完美的声明。但是,我需要进行一些更改,以便它现在从表单中获取用户提交的信息,并根据该信息从数据库中返回结果。

它本质上是一个产品搜索——如果用户搜索“红色”,他们将返回所有红色的项目。如果他们搜索“红色”和“木头”,他们只会返回红色且由木头制成的物品。

这是我的HAVING条款:

HAVING values LIKE "%Red%" AND values LIKE "%Wood%"

如果我有一系列 5 个下拉菜单,每个都有一组不同的术语,我应该尝试HAVING根据用户使用的下拉菜单动态构建子句吗?这将如何完成?

4

3 回答 3

1

我会选择静态 SQL 语句,因为用户可以从中选择五个“选项”。

我要做的是使用一个空字符串作为表示特定选项“无限制”的值,所以我的陈述是这样的:例如

HAVING `values` LIKE CONCAT('%',:b1,'%')
   AND `values` LIKE CONCAT('%',:b2,'%')
   AND `values` LIKE CONCAT('%',:b3,'%')
   AND `values` LIKE CONCAT('%',:b4,'%')
   AND `values` LIKE CONCAT('%',:b5,'%')

仅对选项 1 和 2 应用限制,对选项 3 没有限制,例如

$sth->bind_param(':b1','Red');
$sth->bind_param(':b2','Wood');
$sth->bind_param(':b3','');
$sth->bind_param(':b4','');
$sth->bind_param(':b5','');

仅对选项 2 应用限制,例如

$sth->bind_param(':b1','');
$sth->bind_param(':b2','Wood');
$sth->bind_param(':b3','');
$sth->bind_param(':b4','');
$sth->bind_param(':b5','');

这允许您拥有一个静态语句,唯一需要更改的是为绑定参数提供的值。


也可以使用 NULL 值来表示选项的“无限制”,但是当提供 NULL 值时,您需要修改 SQL 语句以执行“无限制”。要么专门检查 NULL 值,例如

HAVING ( `values` LIKE CONCAT('%',:b1,'%') OR :b1 IS NULL )
   AND ( `values` LIKE CONCAT('%',:b2,'%') OR :b2 IS NULL )
   AND ( `values` LIKE CONCAT('%',:b3,'%') OR :b3 IS NULL )

- 或 - 将 NULL 转换为空字符串以用于 LIKE 谓词,例如

HAVING `values` LIKE CONCAT('%',IFNULL(:b1,''),'%')
   AND `values` LIKE CONCAT('%',IFNULL(:b2,''),'%')
   AND `values` LIKE CONCAT('%',IFNULL(:b3,''),'%')

同样的技术也适用于 WHERE 子句。您可能需要考虑 WHERE 子句是否更适合您的情况。(我们无法从提供的信息中判断。)

但请注意,HAVING 子句不限制语句中包含哪些行;相反,HAVING 子句仅限制返回结果集中的哪些行。HAVING 子句几乎在执行计划中最后应用(我认为它后面只有 ORDER BY 和 LIMIT。

HAVING 子句可以应用于聚合,而 WHERE 子句不能这样做。HAVING 子句可以引用 SELECT 列表中的列,而 WHERE 子句不能这样做。

(还要注意 VALUES 是一个保留字,如果它不合格(前面有alias.,可能需要用反引号括起来。)

于 2012-08-07T20:09:03.370 回答
0

不,您不应该构建 HAVING 子句。

是的,您可以按照您的建议构建 WHERE 子句。

HAVING 用于对组施加涉及聚合函数的条件。

于 2012-08-07T19:50:30.460 回答
0

这种方法适用于涉及更多条件的情况,但您也可以在 5 上使用它们。将您的菜单值收集到一个临时表中,然后在 LIKE 条件下将它们内部连接到您的查询中

SELECT .... FROM MyTable
INNER JOIN  MyTempTable
ON values LIKE '%' + MenuValue '%'
于 2012-08-07T19:58:48.810 回答