2013-05-15 40 views
0

我正在开发一个网站,该网站允许用户列出待售的船只和游艇。有一个mysql数据库有一个表“游艇”,其他领域有“制造”和“模型”。MySql搜索两个组合字段的查询

当有人来到该网站寻找出售船只时,有一个搜索表单,其中一个选项是将制造商和/或模型输入到文本字段中。有关在搜索结果页上的条款是以下

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

这是工作,如果有人进入要么厂名模型但如果他们进入两者。

例如,如果有人输入“Jeanneau”,制造商会发现该制造的船,或者如果他们进入了“Sun Odyssey”模型,它会找到该模型的船,但是如果他们进入“ Jeanneau Sun奥德赛“它变得空虚。

有没有一种方法来编写一个查询,其中所有三种方式进入上述搜索条件会找到船?

这里是网站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); 
+0

你可以发布你的整个查询? –

+0

当两个都进入你的搜索一个领域与制造和模型,所以它失败了,你需要明确分开2,使用2个输入,或拆分文本用户输入 – 2013-05-15 20:04:17

+0

谢谢达贡,是的,我明白为什么它不是工作中,我想到了对两个输入字段进行筛选,但我想知道是否还有其他选项,但是吐出它们的问题是无法分辨哪些词是模型的成分,我想我可以搜索每个词单词,但会带来太多的结果。 –

回答

1

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

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

该命令替换|所有空白,即在正则表达式作为OR所有可搜索字段串联的动力类查询。它的速度在重型交通网站可能有问题,但相当紧凑,并且易于添加更多的领域。

+0

这么容易做到。 RLIKE在mysql问题的答案中远未得到充分利用。也像concat_ws一样。人们的参考文献是CONCAT_WS(http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat-ws)和RLIKE(http://dev.mysql.com/doc/refman /5.0/en/regexp.html#operator_regexp) – JClaspill

+0

我得到这个错误的preg_replace线解析错误:语法错误,意外的'/',期待')'在C:\ xampp \ htdocs \ yachtsoffered \ results.php on第70行 –

+0

对不起,当然应该引用regexp字符串... –

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%' 
-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%'"; 
} 
+0

只是注意到一个错误 - 将解决! –

+0

这里需要一些[适当的SQL转义](http://bobby-tables.com/php)。 – tadman

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

+0

我已经在这个位置的次数,并不知道你可以做到这一点!我现在要去改变一些搜索,所以我把它放在我的代码中 - 谢谢 – 2013-05-15 20:30:34

+0

@Lagon'%searchstring'' @Dagon查询效率不高。 –

+0

LIKE中的反转参数是很好的特性,但在这里它会使任何事情都很难找到 - 你必须提供精确的制作和模型,可选地分开,前缀和后面跟任何不相关的东西,但没有结果用于只有make或只有模型的查询或与每一个的一部分。它会发现''123 Jeanneau 123 Sea Odyssey 213“',但没有''Jeanneau Odyssey”' –

0

谢谢大家我结束了使用上述

开发无效居民的解决方案我修改我的代码如下,

获得的价值和逃避这里是代码,

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”。

但是,这是一个很大的改进,从我了。

感谢所有

罗布·芬威克