0

我正在开发一个允许用户列出待售船只和游艇的网站。有一个 mysql 数据库,它有一个表“yachts”,其中包括“make”和“model”。

当人们来到该网站寻找待售船只时,会有一个搜索表单,其中一个选项是在文本字段中输入品牌和/或型号。结果页面上相关的where子句如下

WHERE ( make LIKE '%$yacht_make%' OR model  LIKE '%$yacht_make%') 

如果有人输入品牌 型号,但如果他们同时输入,则此方法有效。

例如,如果有人输入品牌“Jeanneau”,它会找到具有该品牌的船,或者如果他们输入模型“Sun Odyssey”,它会找到该模型的船,但如果他们输入“Jeanneau Sun Odyssey”它是空的。

有没有办法编写一个查询,输入上述搜索条件的所有三种方式都可以找到船?

这是网站http://yachtsoffered.com/

谢谢,

罗布·芬威克

编辑:

查询是用 php 脚本构建的,这里是脚本

    if(!empty($yacht_id)) {
    $where = " WHERE yacht_id = $yacht_id ";
} else {
    $where = " WHERE ( make LIKE '%$yacht_make%' OR model  LIKE '%$yacht_make%') ";
    if(!empty($year_from) && !empty($year_to)){
        $where .= "AND ( year BETWEEN $year_from AND $year_to ) ";
    }
    if(!empty($length_from) && !empty($length_to)){
        $where .= "AND ( length_ft BETWEEN $length_from AND $length_to ) ";
    }
    if(!empty($price_from) && !empty($price_to)){
        $where .= "AND ( price BETWEEN $price_from AND $price_to ) ";
    }
    if ($sail_power != 2){
        $where .= "AND ( sail_power = $sail_power ) ";
    }
    if (count($material_arr) > 0){
        $material = 'AND  (';
        foreach ($material_arr as $value) {
            $material .= ' material LIKE \'%' . $value . '%\' OR';
        }
        $material = substr_replace ( $material , ') ' , -2 );
        $where .= $material;
    }
    if (count($engine_arr) > 0){
        $engine = 'AND  (';
        foreach ($engine_arr as $value) {
            $engine .= ' engine LIKE \'%' . $value . '%\' OR';
        }
        $engine = substr_replace ( $engine , ') ' , -2 );
        $where .= $engine;
    }
    if (count($type_arr) > 0){
        $type = 'AND  (';
        foreach ($type_arr as $value) {
            $type .= ' type LIKE \'' . $value . '\' OR';
        }
        $type = substr_replace ( $type , ') ' , -2 );
        $where .= $type;
    }
    if (count($region_arr) > 0){
        $region = 'AND  (';
        foreach ($region_arr as $value) {
            $region .= ' region LIKE \'' . $value . '\' OR';
        }
        $region = substr_replace ( $region , ') ' , -2 );
        $where .= $region;
    }       
        $where .= 'AND ( active = 1 ) ORDER BY yacht_id DESC';
}

$sql = "SELECT * FROM $tbl_name $where LIMIT $start, $limit";
$result = mysql_query($sql);
4

5 回答 5

1

有很多方法可以做到这一点,我认为最简单的一种是:

$search = preg_replace('/\s+/','|', $yacht_make);
$sql = "select * from yacht where concat_ws(' ',make,model) rlike '$search'";

这会将所有空格替换|为 , 用于OR连接所有可搜索字段的类似正则表达式的查询。它的速度在流量较大的站点中可能存在问题,但非常紧凑且易于添加更多字段。

于 2013-05-15T20:11:06.090 回答
0

您的问题是,在您的查询中,您正在搜索确切的子字符串“Jeanneau Sun Odyssey”,它既不是品牌也不是模型。

最简单的解决方案是使用分离输入框的品牌和型号。但是如果你真的需要使用单个输入框,你最好的办法是分割空格并为每个单独的单词添加子句,所以你的查询最终看起来像

WHERE make like '%sun%' OR model like '%sun%' 
OR make like '%odyssey%' OR model like '%odyssey%' 
OR make like '%Jeanneau%' OR model like '%Jeanneau%'
于 2013-05-15T20:07:49.933 回答
0

您还可以使用:

WHERE make LIKE '%$yacht_make%'
   OR model  LIKE '%$yacht_make%'
   OR '$yacht_make' LIKE CONCAT('%', make, '%', model, '%')
   OR '$yacht_make' LIKE CONCAT('%', model, '%', make, '%')

它不会非常有效并且仍然无法捕捉所有可能性,例如,如果用户提供品牌和模型名称的一部分,例如'Jeanneau Odyssey'或以错误的顺序:Sun Jeanneau Odyssey

于 2013-05-15T20:17:33.040 回答
0

谢谢大家,我最终使用了上面的 dev-null-dweller 解决方案

我修改了我的代码如下,

获取值并在此处转义是代码,

    if (isset($_GET['yacht_make'])) {
    $yacht_make  = cleanString($_GET['yacht_make']);
    $yacht_make = preg_replace('/\s+/','|', $yacht_make);
} else {
    $yacht_make = NULL;
}

我修改了上面发布的php查询构建代码的前几行以阅读,

if(!empty($yacht_id)) {
    $where = " WHERE yacht_id = $yacht_id ";
} else {

    $where = " WHERE ( yacht_id LIKE '%' )";

    if(!empty($yacht_make)){
        $where .= "AND ( CONCAT_WS(' ',make,model) RLIKE '$yacht_make') ";
    }

它工作得很好,虽然它带来的结果比我想要的“Jeanneau Sun Odyssey”更多,因为它带来了“Bayliner Sunbridge”,我认为因为它匹配“Sun”。

但这与我所拥有的相比有了很大的改进。

谢谢大家

罗布·芬威克

于 2013-05-15T21:36:33.480 回答
-1

检查您的站点后,您似乎只从一个文本字段中获取输入并在每个字段中搜索该字符串。

因此,您可以使用全文搜索 ( linkie ),也可以用空格分割字符串并即时生成 WHERE 原因。这是一个粗略的例子:

$searchterms = explode (' ', $input);

$sql .= "... WHERE"; /* obviously need the rest of your query */


foreach ($searchterms as $term) {
  if ((substr ($string, -5) != 'WHERE') && 
      (substr ($string, -3) == ' ||') { $sql .= " ||"; }
  $sql .= " make LIKE '%$term%' || model LIKE '%$term%'";
}
于 2013-05-15T20:08:53.717 回答