我正在开发一个网站,允许用户列出待售的游艇和游艇。有一个mysql数据库有一个表“游艇”,其他字段是“制造”和“模型”。
当人们来到网站寻找待售船只时,会有一个搜索表单,其中一个选项是将制作和/或模型输入到文本字段中。结果页面上的相关where子句如下
WHERE ( make LIKE '%$yacht_make%' OR model LIKE '%$yacht_make%')
如果有人输入 或模型,那么这是有效的,但如果他们同时输入这两个模型,则无效。
例如,如果有人进入“Jeanneau”,制造,它会找到带有该制造的船,或者如果他们进入“太阳奥德赛”,模型,它会找到该型号的船,但如果他们进入“Jeanneau”太阳奥德赛“它空洞。
是否有办法编写一个查询,其中输入上述搜索条件的所有三种方式都可以找到该船?
以下是网站http://yachtsoffered.com/
谢谢,
Rob Fenwick
编辑:
查询是使用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 :(得分:1)
有很多方法可以做到,我认为最简单的方法是:
$search = preg_replace('/\s+/','|', $yacht_make);
$sql = "select * from yacht where concat_ws(' ',make,model) rlike '$search'";
这会将所有空格替换为|
,在所有可搜索字段的连接中,在用于regexp驱动的查询中用作OR
。在繁忙的交通站点,它的速度可能会有问题,但是非常紧凑,并且容易添加更多的场地。
答案 1 :(得分:0)
您的问题是,在您的查询中,您正在搜索确切的子串“Jeanneau Sun Odyssey”,它既不是制作也不是模型。
最简单的解决方案是使用分离make和model的输入框。但是如果你真的需要使用一个输入框,你最好的选择是分隔空格并为每个单独的单词添加子句,这样你的查询最终会看起来像
WHERE make like '%sun%' OR model like '%sun%'
OR make like '%odyssey%' OR model like '%odyssey%'
OR make like '%Jeanneau%' OR model like '%Jeanneau%'
答案 2 :(得分: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
。
答案 3 :(得分: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”,我认为因为它匹配“太阳”。
但它与我的相比有了很大改进。
全部谢谢
Rob Fenwick
答案 4 :(得分:-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%'";
}