欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL高效模糊搜索之内置函数locate instr position find_in_set使用详解

程序员文章站 2022-03-18 14:54:53
常用的一共有4个方法,如下: 1.使用locate()方法 普通用法: select`column`from`table`wherelocate('keywo...

常用的一共有4个方法,如下:

1.使用locate()方法

普通用法:

select`column`from`table`wherelocate('keyword',`condition`)>0

类似于java的indexof();

不过locate()只要找到返回的结果都大于0(即使是查询的内容就是最开始部分),没有查找到才返回0;

指定起始位置:

select locate('bar','foobarbar',5);(从foobarbar的第五个位置开始查找)

2.使用instr()函数(据说是locate()的别名函数)

select `column` from `table` where instr(`condition`,‘keyword')>0

唯一不同的是查询内容的位置不同

3.使用position()方法,(据说也是locate()方法的别名函数,功能一样)

select `column` from `table` where position(‘keyword' in `condition`)

不过它不再是通过返回值来判断,而是使用关键字in

4.使用find_in_set()函数

如:find_in_set(str,strlist),strlist必须要是以逗号分隔的字符串

如果字符串str是在的strlist组成的n子串的字符串列表,返回值的范围为1到n

sql>selectfind_in_set('b','a,b,c,d');
---------------------------------------------------------+
|selectfind_in_set('b','a,b,c,d')|
---------------------------------------------------------+
|2|
---------------------------------------------------------+
1rowinset(0.00sec)

总结:locate、position和instr的差別只是参数的位置不同,同时locate多一个起始位置的参数外,两者是一样的。

find_in_set()比较特殊,但它们都是返回要查找的子字符串在指定字符串中的位置。

速度上前3个要比用like稍快一点。(不过这四个函数都不能使用索引)

下面为再为大家介绍一下mysql中like的使用方法

mysql的like语句中的通配符:百分号、下划线和escape

%:表示任意个或多个字符。可匹配任意类型和长度的字符。

sql代码

select * from user where username like '%huxiao'; 

select * from user where username like 'huxiao%'; 

select * from user where username like '%huxiao%';

另外,如果需要找出u_name中既有“三”又有“猫”的记录,请使用and条件

select * from [user] where u_name like ‘%三%' and u_name like ‘%猫%'

若使用 select * from [user] where u_name like ‘%三%猫%'

虽然能搜索出“三脚猫”,但不能搜索出符合条件的“张猫三”。

_:表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句:(可以代表一个中文字符)
 

sql代码  

select * from user where username like '_'; 

select * from user where username like 'huxia_'; 

select * from user where username like 'h_xiao'; 

 如果我就真的要查%或者_,怎么办呢?使用escape,转义字符后面的%或_就不作为通配符了,注意前面没有转义字符的%和_仍然起通配符作用

sql代码  

select username from gg_user where username like '%xiao/_%' escape '/';

select username from gg_user where username like '%xiao/%%' escape '/';

mysql 通配符

sql的模式匹配允许你使用“_”匹配任何单个字符,而“%”匹配任意数目字符(包括零个字符)。在 mysql中,sql的模式缺省是忽略大小写的。下面显示一些例子。

注意在你使用sql模式时,你不能使用=或!=;而使用like或not like比较操作符。

为了找出以“b”开头的名字:

mysql> select * from pet where name like "b%";
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| buffy | harold | dog | f | 1989-05-13 | null |
| bowser | diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+

为了找出以“fy”结尾的名字:

mysql> select * from pet where name like "%fy";
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| fluffy | harold | cat | f | 1993-02-04 | null |
| buffy | harold | dog | f | 1989-05-13 | null |
+--------+--------+---------+------+------------+-------+

为了找出包含一个“w”的名字:

mysql> select * from pet where name like "%w%";
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| claws | gwen | cat | m | 1994-03-17 | null |
| bowser | diane | dog | m | 1989-08-31 | 1995-07-29 |
| whistler | gwen | bird | null | 1997-12-09 | null |
+----------+-------+---------+------+------------+------------+

为了找出包含正好5个字符的名字,使用“_”模式字符:

mysql> select * from pet where name like "_____";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| claws | gwen | cat | m | 1994-03-17 | null |
| buffy | harold | dog | f | 1989-05-13 | null |
+-------+--------+---------+------+------------+-------+

由mysql提供的模式匹配的其他类型是使用扩展正则表达式。当你对这类模式进行匹配测试时,使用regexp和not regexp操作符(或rlike和not rlike,它们是同义词)。

扩展正则表达式的一些字符是:

“.”匹配任何单个的字符。

一个字符类“[...]”匹配在方括号内的任何字符。

例如,“[abc]”匹配“a”、“b”或“c”。为了命名字符的一个范围,使用一个“-”。“[a-z]” 匹配任何小写字母,而“[0-9]”匹配任何数字。

“ * ”匹配零个或多个在它前面的东西。

例如,“x*”匹配任何数量的“x”字符,“[0-9]*”匹配的任何数量的数字,而“.*”匹配任何数量的任何东西。

正则表达式是区分大小写的,但是如果你希望,你能使用一个字符类匹配两种写法。

例如,“[aa]”匹配小写或大写的“a”而“[a-za-z]”匹配两种写法的任何字母。

如果它出现在被测试值的任何地方,模式就匹配(只要他们匹配整个值,sql模式匹配)。

为了定位一个模式以便它必须匹配被测试值的开始或结尾,在模式开始处使用“^”或在模式的结尾用“$”。

为了说明扩展正则表达式如何工作,上面所示的like查询在下面使用regexp重写:

为了找出以“b”开头的名字,使用“^”匹配名字的开始并且“[bb]”匹配小写或大写的“b”:

mysql> select * from pet where name regexp "^[bb]";
+--------+--------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+------------+
| buffy | harold | dog | f | 1989-05-13 | null |
| bowser | diane | dog | m | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+

为了找出以“fy”结尾的名字,使用“$”匹配名字的结尾:

mysql> select * from pet where name regexp "fy$";
+--------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+--------+--------+---------+------+------------+-------+
| fluffy | harold | cat | f | 1993-02-04 | null |
| buffy | harold | dog | f | 1989-05-13 | null |
+--------+--------+---------+------+------------+-------+

为了找出包含一个“w”的名字,使用“[ww]”匹配小写或大写的“w”:

mysql> select * from pet where name regexp "[ww]";
+----------+-------+---------+------+------------+------------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+------------+
| claws | gwen | cat | m | 1994-03-17 | null |
| bowser | diane | dog | m | 1989-08-31 | 1995-07-29 |
| whistler | gwen | bird | null | 1997-12-09 | null |
+----------+-------+---------+------+------------+------------+

既然如果一个正规表达式出现在值的任何地方,其模式匹配了,就不必再先前的查询中在模式的两方面放置一个通配符以使得它匹配整个值,就像如果你使用了一个sql模式那样。

 为了找出包含正好5个字符的名字,使用“^”和“$”匹配名字的开始和结尾,和5个“.”实例在两者之间:

mysql> select * from pet where name regexp "^.....$";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| claws | gwen | cat | m | 1994-03-17 | null |
| buffy | harold | dog | f | 1989-05-13 | null |
+-------+--------+---------+------+------------+-------+

你也可以使用“{n}”“重复n次”操作符重写先前的查询:

mysql> select * from pet where name regexp "^.{5}$";
+-------+--------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+-------+--------+---------+------+------------+-------+
| claws | gwen | cat | m | 1994-03-17 | null |
| buffy | harold | dog | f | 1989-05-13 | null |
+-------+--------+---------+------+------------+-------+

以上是mysql模糊搜索方法like的使用方法,与前locate instr position这三个内置函数相比性能上要慢些,无论哪种模糊搜索在查询时都会消耗大量服务器资源所以在实际工作中我们应尽量少用模糊搜索