我写了SELECT
语句完美无缺。但是,我需要进行一些更改,以便它现在从表单中获取用户提交的信息,并根据该结果返回数据库中的结果。
它基本上是一个产品搜索 - 如果用户搜索“红色”,他们将获得所有红色的项目。如果他们搜索“红色”和“木头”,他们将只收回红色和木头制成的物品。
这是我的HAVING
条款:
HAVING values LIKE "%Red%" AND values LIKE "%Wood%"
如果我有一系列5个下拉菜单,每个菜单都有不同的术语集,我应该根据用户使用的下拉菜单动态构建HAVING
子句吗?怎么会这样做?
答案 0 :(得分: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.
,则可能需要用反引号括起来。)
答案 1 :(得分:0)
不,你不应该构建HAVING子句。
是的,您可以按照建议构建WHERE子句。
HAVING用于强制涉及群组聚合功能的条件。
答案 2 :(得分:0)
这种方法适用于涉及更多条件的地方,但您也可以在5上使用它们。将菜单值收集到临时表中,然后将它们连接到LIKE条件
上的查询SELECT .... FROM MyTable
INNER JOIN MyTempTable
ON values LIKE '%' + MenuValue '%'