我正在开发一个允许用户列出待售船只和游艇的网站。有一个mysql数据库,有一个表"游艇",其中包括"制造"和"模型"。
当人们来到该网站寻找待售船只时,有一个搜索表单,其中一个选项是在文本字段中输入品牌和/或型号。结果页面上的相关 where 子句如下
WHERE ( make LIKE '%$yacht_make%' OR model LIKE '%$yacht_make%')
如果有人输入品牌或型号,则此功能有效,但如果同时输入两者,则无效。
例如,如果有人输入"亚诺",它找到带有该品牌的船,或者如果他们输入模型"太阳奥德赛",它会找到该模型的船,但如果他们输入"亚诺太阳奥德赛",它就会出现空的。
有没有办法编写一个查询,输入上述搜索条件的所有三种方法都可以找到船?
这是网站 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);
有很多方法可以做到这一点,在我看来最简单的方法是:
$search = preg_replace('/'s+/','|', $yacht_make);
$sql = "select * from yacht where concat_ws(' ',make,model) rlike '$search'";
这会将所有空格替换为 |
,在类似正则表达式的查询中用作所有可搜索字段串联的OR
。它的速度在繁重的运输站点中可能值得怀疑,但非常紧凑且易于添加更多字段。
您的问题是,在查询中,您正在搜索确切的子字符串"亚诺太阳奥德赛",它既不是品牌也不是模型。
最简单的解决方案是用于分隔品牌和型号的输入框。但是,如果您确实需要使用单个输入框,最好的选择是拆分空格并为每个单独的单词添加子句,因此您的查询最终将看起来像
WHERE make like '%sun%' OR model like '%sun%'
OR make like '%odyssey%' OR model like '%odyssey%'
OR make like '%Jeanneau%' OR model like '%Jeanneau%'
谢谢大家,我最终使用了上面的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') ";
}
它运行良好,尽管它带来了比我想要的更多的结果"亚诺太阳奥德赛",因为它带来了"Bayliner Sunbridge",我认为是因为它与"太阳"匹配。
但这比我有一个很大的进步。
谢谢大家
罗伯·芬威克
您还可以使用:
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
。
签出您的网站后,您似乎只从一个文本字段中获取输入并在每个字段中搜索该字符串。
因此,您可以使用全文搜索(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%'";
}