【问题标题】:Constructing a multi-argument MySQL Search Query构造一个多参数 MySQL 搜索查询
【发布时间】:2009-09-21 18:27:11
【问题描述】:

我正在尝试使用多个参数在 MySQL 中构造一个搜索查询,但我不能完全正确。

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

这里是一些背景信息:

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

  1. 职位名称
  2. 工作类型
  3. 职位描述
  4. 工作地点

职位名称:这是职位信息的 1-5 字标题。根据输入的方式可能会有所不同

工作类型:这是工作类型的三个字母代码。

职位描述:这是对职位和职责的简短描述

位置:这是一个城市或城镇

用户将使用搜索表单进行搜索。搜索表单由三部分组成。两个文本字段,“关键字”和“位置”;和一个列出大约 20 种工作类型的下拉框。这将允许他们在职位列表的三个字母代码之间进行选择。

我想从表单的这三个部分中获取信息,并使用它们来搜索我的数据库并返回最准确的记录。我已经尝试了几次查询迭代,它要么返回很多不相关的记录,要么没有返回足够多的相关记录。我也无法解释用户故意将表单的某些部分留空的原因。

我当前的查询看起来像这样:

选择 * FROM my_jobs_table WHERE category = '用户指定的工作类型' OR job_title LIKE '用户指定的工作关键字' OR job_description LIKE '用户指定的工作关键字' OR location LIKE "% User Specified Job Location%"

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

【问题讨论】:

  • jobtype 是 int 吗?如果是这样,您需要删除查询中的 ''。
  • Jonas,jobtype 甚至不是 OP 查询的一部分。他清楚地说这是一个 3 个字母的代码,而不是 int。另外,mysql不关心你是否在数字周围加上引号,所以没关系。
  • 维克多,你能定义“不工作”吗?
  • 是的,“不起作用”是指即使我搜索特定记录,查询也会返回过于广泛的结果选择。例如。如果我在医疗保健 (HEA) 类别下搜索科罗拉多州的护理工作,查询将返回科罗拉多州的每个工作、每个护理工作以及 HEA 类别中的每个工作。我只希望它返回具有 HEA 类别、关键字 Nursing 和位置 Colorado 的工作。

标签: mysql


【解决方案1】:

各种“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 或应用程序代码中解决该问题,如果用户不提供默认值,则设置默认值,或者将它们返回到表单并告诉他们如果不为必填字段提供值就无法继续。

【讨论】:

  • 感谢比尔和其他所有人,我会尝试这种方法并再次发布我的结果。
【解决方案2】:

如果您使用 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。)至少,请确保您正在转义用户提供的查询部分。

【讨论】:

    【解决方案3】:

    在这种情况下,我要做的是设置一个没有 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多