我正在尝试使用多个参数在MySQL中构建搜索查询,但我无法正确理解。
我从表单接收搜索参数,并使用它们动态构建我的查询。
以下是一些背景信息:
我有一个包含工作信息的MySQL数据库。我想搜索四列:
职位名称:这是职位的1-5字标题。它可以根据输入的方式而有所不同
作业类型:这是作业类型的三字母代码。
职位描述:这是职位和职责的简短描述
位置:这是一个城市或城镇
用户将使用搜索表单进行搜索。搜索表单由三部分组成。两个文本字段,“关键字”和“位置”;以及一个列出约20种工作类型的下拉框。这将允许他们在职位列表的三个字母代码之间进行选择。
我想从表单的这三个部分获取信息,并使用它们来搜索我的数据库并返回最准确的记录。我已经尝试了几次我的查询迭代,它要么返回很多不相关的记录,要么返回足够的相关记录。我也无法说明用户故意将表格中的部分留空。
我当前的查询看起来像这样:
select * FROM my_jobs_table WHERE category = 'User specified job type' OR job_title LIKE 'User specified Job keyword' OR job_description LIKE 'User specified Job keyword ' OR location LIKE "% User Specified Job Location%"
这对我不起作用。有什么建议吗?
答案 0 :(得分:3)
各种“LIKE '%keyword%'
”解决方案效果不佳。我建议您使用FULLTEXT INDEX代替(假设您的表使用MyISAM存储引擎)。
CREATE FULLTEXT INDEX jobsearch_idx ON my_jobs_table (job_title, job_description, location);
然后您可以使用MATCH()
运算符进行搜索:
SELECT * FROM my_jobs_table
WHERE MATCH(job_title, job_description, location) AGAINST( ? );
替换上面有“?
”的用户指定的关键字。顺便说一句,我假设一个合理的设计是允许在标题或描述中出现位置关键字。因此,在您的应用程序中,将关键字与位置选择(空格分隔)连接起来,并将其用于查询参数。
我故意将category
从该示例中删除,因为我假设您希望类别名称完全匹配。所以使用AND
运算符添加它,如下所示:
SELECT * FROM my_jobs_table
WHERE category = ?
AND MATCH(job_title, job_description, location) AGAINST( ? );
替换上面两个“?
”占位符的两个用户选项(类别和关键字)。使用查询参数,而不是变量插值。
当然,MySQL全文索引还有很多其他选项。例如,您可能希望使用搜索修饰符“IN BOOLEAN MODE
”。我不会在这里完整地描述它们,你应该阅读手册部分以了解更多信息。
MySQL 5.1 Reference Manual: Full-Text Search Functions
对于用户将表单字段留空的处理情况,这是一个与搜索数据库分开的不同问题。您应该在Javascript或应用程序代码中解决该问题,如果用户未提供默认值,则设置默认值,或者将其返回到表单并告诉他们如果不为必填字段赋值,则无法继续。
答案 1 :(得分:1)
如果你正在使用LIKE,你应该在字符串的两端放置%。 %是通配符:
SELECT * FROM my_jobs_table
WHERE category = 'User specified job type'
OR job_title LIKE '%keyword%'
OR job_description LIKE '%keyword%'
OR location LIKE '%location%'
但您应该使用参数化查询。 (有关示例,请参阅here。)至少,请确保您正在转义用户提供的查询部分。
答案 2 :(得分:0)
在这种情况下我做的是设置一个没有JOIN或WHERE的基本查询。然后我遍历请求值并构建我的查询。像这样:
$q="SELECT * FROM my_jobs_table";
foreach($post as $key=>$value) { //assuming you cleaned & validated the $_POST into $post
switch($key)
case 'category':
$wheres[]="$key ='$value'";
break;
case 'job_title':
case 'job_description':
case 'location':
$wheres[]="$key LIKE '%{$value}%'";
break;
}
}
$where='WHERE ' . implode(' AND ', $wheres); //put on a condition to check for empty($wheres)
$q .= $where;