构造一个多参数的MySQL搜索查询

时间:2009-09-21 18:27:12

标签: mysql

我正在尝试使用多个参数在MySQL中构建搜索查询,但我无法正确理解。

我从表单接收搜索参数,并使用它们动态构建我的查询。

以下是一些背景信息:

我有一个包含工作信息的MySQL数据库。我想搜索四列:

  1. 职位名称
  2. 工作类型
  3. 职位描述
  4. 工作地点
  5. 职位名称:这是职位的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%"
    

    这对我不起作用。有什么建议吗?

3 个答案:

答案 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;