我尝试使用LIKE
查询在我的小工具中实施搜索。
现在我有了这个新要求,我必须像Android搜索一样进行搜索..
查询:
$stmt = $conn->prepare("SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE LOWER(GUEST_FIRST_NAME) LIKE ? OR LOWER(GUEST_NAME) LIKE ?");
$stmt->execute(array('%'.strtolower($searchFilter).'%','%'.strtolower($searchFilter).'%' ));
假设我在数据库中有一个字符串Syed Haider Hassan
如果我使用给定的查询在数据库表中搜索san
,它会在上面的字符串中找到我。
因此,如果我把任何匹配在字符串内部或任何地方匹配,它将得到我这个字符串,
但我想要的是,当我在数据库Hai
或Has
或Sy
中搜索时,它应该为我提供此字符串,但如果我搜索san
或甚至{ {1}},查询不应该显示此字符串。
意味着如果我搜索它必须用assan
搜索,而不是从中间搜索。
我认为如果我从开始删除startwith
可能是可能的,但问题是查询只会在Syed上看到startwith,我希望它在每个单词上应用startwith,因为单词是由空格分隔的。不同地搜索%
Syed
Haider
..
我知道上面我试图解释的是非常令人困惑的,主要是因为我的英语不好。 但简单来说,如果你有Android手机,我有Galaxy S4,搜索你的通讯录中的任何名字。如果你从单词的中间搜索它将不会搜索,但如果你从单词的开头搜索它将搜索,但那不是它。如果您的联系人姓名是由空格分隔的两个单词的组合 然后它还会检查第二个单词的第一个字母。
我希望我很清楚,但我不知道如何实现该查询。如果有人可以将我的查询更新为这个新的搜索条件,我将非常高兴。
=======================================
更新
好吧,我尝试了使用try catch的回答中建议的匹配,我得到了这个错误。这是我试过的代码。
Hassan
任何想法如何解决?
===================================
更新2
好的,我只是把事实放在这里。 这是我的表格结构。
如果我喜欢使用通配符%%,它甚至会从名称中间搜索。
让我们在屏幕截图中看到突出显示的名称,突出显示的名称为$search_words = "+" . str_replace (" ", "* +", $searchFilter )."*";
try {
$stmt = $conn->prepare("SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE MATCH (GUEST_FIRST_NAME, GUEST_NAME) against (:SEARCH in boolean mode)");
$stmt->bindValue(':SEARCH', $search_words, PDO::PARAM_STR);
$stmt->execute();
}
catch(PDOException $e){
echo 'ERROR: ' . $e->getMessage();
}
。
如果我使用%enry%搜索外卡,它会找到我这一行。
但我不想要那个,我希望搜索应该用名字开头。
e-g如果我搜索Lukasz Henryk
或Luk
或Hen
或甚至He
,它应该会找到我这一行。意味着开始字母表很重要,如果开始字母表不匹配,那么就不要给我这一行。
我也尝试了像H
这样的通配符,但它不起作用,因为它只适用于Henr%
,它将整列视为单个字符串。
是否有办法告诉查询在空格后搜索起始字母?
请有人帮帮我。
答案 0 :(得分:1)
正如其他人所说,全文索引是要走的路,这就是你希望你的查询看起来的样子,+
使所有需要的单词留下来查找任何单词。您不能使用"
双引号和*
通配符,这是合理的,因为双引号表示exact
个单词。使用外卡时不能使用它。 (或者至少我还没有办法做到这一点)
SELECT
ROOM,
GUEST_NAME,
GUEST_FIRST_NAME,
CONFIRMATION_NO,
DEPARTURE,
PWD
FROM
RESERVATION_GENERAL_2
WHERE
MATCH(GUEST_NAME, GUEST_FIRST_NAME)
AGAINST
( '+word* +word2*' IN BOOLEAN MODE )
基本上
$search_words = '';
foreach( explode(' ', $search) as $words ){
$search_words .= '+'.$word.'* ';
}
和
...
WHERE
MATCH(GUEST_NAME, GUEST_FIRST_NAME)
AGAINST
( :search_words IN BOOLEAN MODE )
$stmt->bindValue(':search_words', $search_words, PDO::PARAM_STR);
等等...
但你必须有一个全文索引,在这种情况下是GUEST_NAME, GUEST_FIRST_NAME
上的复合索引。
另见
答案 1 :(得分:0)
你可以使用MySQL:s MATCH AGAINST。请记住,您必须制作包含GUEST_FIRST_NAME和GUEST_NAME的FULLTEXT索引(按此顺序)。
只是一个例子:
$string = "syed haider";
$search_words = "+" . str_replace (" ", "* +", $string )."*";
$query = "SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE MATCH (GUEST_FIRST_NAME) against ('$search_words' in boolean mode) OR MATCH (GUEST_NAME) against ('$search_words' in boolean mode)";
// SELECT ROOM, GUEST_NAME, GUEST_FIRST_NAME, CONFIRMATION_NO, DEPARTURE, PWD FROM RESERVATION_GENERAL_2 WHERE MATCH (GUEST_FIRST_NAME) against ('+syed* +haider*' in boolean mode) OR MATCH (GUEST_NAME) against ('+syed* +haider*' in boolean mode)
答案 2 :(得分:0)
表格设置:
CREATE TABLE `user` (
`name` varchar(50) NOT NULL DEFAULT ''
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`name`)
VALUES
('Syed Haider Hassan');
查询:
select * from user where name rlike '[[:<:]]Hass'
返回:
name
Syed Haider Hassan
不匹配查询:
select * from user where name rlike '[[:<:]]san'
返回:
name
答案 3 :(得分:0)
您的问题来自搜索字符串($ search_words =“+”。str_replace(“”,“* +”,$ searchFilter)。“*”;),因为关系运算符是“+, - ,&lt;&gt;等等“,这就是为什么你需要先看到你的完整查询。
采取以下步骤:
RESERVATION_GENERAL_2
添加FULLTEXT索引name_index
(GUEST_FIRST_NAME
,GUEST_NAME
);“尝试以下步骤告诉我们。