MySQL实现模糊查询(REGEXP,LIKE)有2种方式

一是用LIKE/NOT LIKE,
二是用REGEXP/NOT REGEXP(或RLIKE/NOT RLIKE,它们是同义词)。

第一种:标准的SQL模式匹配。

它有2种通配符:“_”和“%”。“_”匹配任意单个字符,而“%”匹配任意多个字符(包括0个)。
举例如下:

 代码如下 复制代码

SELECT * FROM table_name WHERE column_name LIKE 'm%'; #查询某字段中以m或M开头的所有记录
SELECT * FROM table_name WHERE column_name LIKE '%m%'; #查询某字段中包含m或M的所有记录
SELECT * FROM table_name WHERE column_name LIKE '%m'; #查询某字段中以m或M结尾的所有记录
SELECT * FROM table_name WHERE column_name LIKE '_m_'; #查询某字段中3个字符且m或M在中间的所有记录

如果我们想查询包含通配符的字符串该怎么办呢?
比如,50%或_get。
答案就是:转义。可以用来直接转义,或用ESCAPE定义转义字符来进行转义,都只是转义跟在后面的一个字符,

例如:

 代码如下 复制代码

SELECT * FROM table_name WHERE column_name LIKE '%50%%'; /*第2个%被转义,查询某字段包含50%的所有记录*/
SELECT * FROM table_name WHERE column_name LIKE '%50/%%' ESCAPE '/'; #第2个%被转义
SELECT * FROM table_name WHERE column_name LIKE '%_get%' ESCAPE '/'; /*“_”被转义,查询某字段包含_get的所有记录*/

第二种:使用扩展正则表达式的模式匹配。

先来看下扩展正则表达式一些字符的含义:
“.”:匹配任意单个字符
“?”:匹配前面的子表达式0次或1次。
“+”:匹配前面的子表达式1次或多次。
“*”:匹配前面的子表达式0次或多次。x*,表示0个或多个x字符;[0-9]*,匹配任何数量的数字。
“^”:表示匹配开始位置。
“$”:表示匹配结束位置。
“[]”:表示一个集合。[hi],表示匹配h或i;[a-d],表示匹配a、b、c、d中任一个。
“{}”:表示重复的次数。8{5},表示匹配5个8,即88888;[0-9]{5,11},表示匹配5到11个数字。

再来看个例子:

 代码如下 复制代码

SELECT * FROM table_name WHERE column_name REGEXP '^50%{1,3}';

/*查询某字段中以50%、50%%或50%%%开头的所有记录*/

方法三,如果要更高级的就是fulltext全文搜索了

面我们通过实例来一步步把全文检索的过程解释清楚:

首页我们建立表与初始化数据

Sql代码

 代码如下 复制代码
CREATE TABLE IF NOT EXISTS `category` (       
  `id` int(10) NOT NULL auto_increment,       
  `fid` int(10) NOT NULL,       
  `catname` char(255) NOT NULL,       
  `addtime` char(10) NOT NULL,       
  PRIMARY KEY  (`id`),       
  FULLTEXT KEY `catname` (`catname`)       
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;       
      
      
INSERT INTO `category` (`id`, `fid`, `catname`, `addtime`) VALUES      
(1, 0, 'welcome to you!', '1263363380'),       
(2, 0, 'hello phpjs,you are welcome', '1263363416'),       
(3, 0, 'this is the fan site of you', '1263363673');      
   
CREATE TABLE IF NOT EXISTS `category` ( `id` int(10) NOT NULL auto_increment, `fid` int(10) NOT NULL, `catname` char(255) NOT NULL, `addtime` char(10) NOT NULL, PRIMARY KEY (`id`), FULLTEXT KEY `catname` (`catname`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; INSERT INTO `category` (`id`, `fid`, `catname`, `addtime`) VALUES (1, 0, 'welcome to you!', '1263363380'), (2, 0, 'hello phpjs,you are welcome', '1263363416'), (3, 0, 'this is the fan site of you', '1263363673');

 
在具体实例之前,我们分析下msyql全文检索的语法:函数 MATCH() 对照一个文本集(包含在一个 FULLTEXT 索引中的一个或多个列的列集)执行一个自然语言搜索一个字符串。搜索字符串做为 AGAINST() 的参数被给定。搜索以忽略字母大小写的方式执行。说白了就是MATCH给定匹配的列(fulltext类型索引),AGAINST给定要匹配的字符串,多个用空格、标点分开,mysql会自动分隔。

SQL代码

 代码如下 复制代码
SELECT * FROM `category` WHERE MATCH(catname) AGAINST('phpjs')  

 

返回结果:

 代码如下 复制代码

id  fid  catname                                addtime 
2   0    hello phpjs,you are welcome 1263363416

匹配出了含有phpjs关键字的行数据。

 
2、SQL代码

 

 代码如下 复制代码
SELECT * FROM `category` WHERE MATCH (catname) AGAINST ('this')   

 
 
按照上面的思路,第三行数据含有this,因此应该可以匹配出第三行数据的,但事实却奇怪得很,返回结果为空,为什么呢?

原来是mysql指定了最小字符长度,默认是4,必须要匹配大于4的才会有返回结果,可以用SHOW VARIABLES LIKE 'ft_min_word_len' 来查看指定的字符长度,也可以在mysql配置文件my.ini 更改最小字符长度,方法是在my.ini 增加一行比如:ft_min_word_len = 2,改完后重启mysql即可。

 
3、这里我们要确定把最小字符改为2了,因为3行记录都有‘you’,因此心想,匹配‘you’就可以返回所有结果了

SQL代码

 代码如下 复制代码
SELECT * FROM `category` WHERE MATCH (catname) AGAINST ('you')   

 
返回结果还是为空,大跌眼镜了吧,这又是为什么呢?

原来mysql在集和查询中的对每个合适的词都会先计算它们的权重,一个出现在多个文档中的词将有较低的权重(可能甚至有一个零权重),因为在这个特定的集中,它有较低的语义值。否则,如果词是较少的,它将得到一个较高的权重,mysql默认的阀值是50%,上面‘you’在每个文档都出现,因此是100%,只有低于50%的才会出现在结果集中。
 

4、有人会想,我不去管权重大小,只要有匹配的就给我返回结果集中,那么该如何做呢?

mysql到 4.0.1 时,可以使用 IN BOOLEAN MODE 修饰语来执行一个逻辑全文搜索

SQL代码

 代码如下 复制代码
SELECT * FROM `category` WHERE MATCH(catname) AGAINST('you' IN BOOLEAN MODE)  

 
 

总结:1、要注意最小字符的长度;

           2、要注意关键词的权重;

时间: 2025-01-11 22:45:26

MySQL实现模糊查询(REGEXP,LIKE)有2种方式的相关文章

android sqlite使用之模糊查询数据库数据的三种方式

android应用开发中常常需要记录一下数据,而在查询的时候如何实现模糊查询呢?很少有文章来做这样的介绍,所以这里简单的介绍下三种sqlite的模糊查询方式,直接上代码把: package com.example.utils; import java.util.ArrayList; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import

mysql中模糊查询的四种用法介绍_Mysql

下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] WHERE u_name LIKE '%三%' 将会把u_name为"张三","张猫三"."三脚猫","唐三藏"等等有"三"的记录全找出来. 另外,如果需要找出u_name中既有"三"又有

mysql中模糊查询的四种用法介绍

下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] WHERE u_name LIKE '%三%' 将会把u_name为"张三","张猫三"."三脚猫","唐三藏"等等有"三"的记录全找出来. 另外,如果需要找出u_name中既有"三"又有

MySQL 初步安装后更改datadir目录几种方式

链接:http://blog.itpub.net/28602568/viewspace-1663979/ 标题:MySQL 初步安装后更改datadir目录几种方式  作者:lōττéry版权所有[文章允许转载,但必须以链接方式注明源地址,否则追究法律责任.] 注释:       若mysql 安装初步使用rpm默认将db安装到/var/lib/mysql/路径后,想更改db路径,怎么处理呢?  测试步骤:     1. 简单叙述安装步骤     2.更改db目录的2中方式..        

MySql官方手册学习笔记2 MySql的模糊查询和正则表达式_Mysql

SQL模式匹配允许你使用"_"匹配任何单个字符,而"%"匹配任意数目字符(包括零字符).在 MySQL中,SQL的模式默认是忽略大小写的.下面给出一些例子.注意使用SQL模式时,不能使用=或!=:而应使用LIKE或NOT LIKE比较操作符. 要想找出以"b"开头的名字:   mysql> SELECT * FROM pet WHERE name LIKE 'b%'; +--------+--------+---------+------+

MySql like模糊查询通配符使用详细介绍_Mysql

一.SQL模式 SQL的模式匹配允许你使用"_"匹配任何单个字符,而"%"匹配任意数目字符(包括零个字符).在 MySQL中,SQL的模式缺省是忽略大小写的.下面显示一些例子.注意在你使用SQL模式时,你不能使用=或!=:而使用LIKE或NOT LIKE比较操作符. SELECT 字段 FROM 表 WHERE 某字段 Like 条件 其中关于条件,SQL提供了四种匹配模式: 1,%:表示任意个或多个字符.可匹配任意类型和长度的字符. 比如 SELECT * FRO

mysql命令行中执行sql的几种方式总结_Mysql

1.直接输入sql执行 MySQL> select now(); +---------------------+ | now() | +---------------------+ | 2013-09-18 13:55:45 | +---------------------+ 1 row in set (0.00 sec) 2.执行编写好的sql脚本 mysql> source H:/1.sql +---------------------+ | now() | +--------------

mysql模糊查询like和regexp小结_Mysql

在mysql中实现模糊查询的有like和regexp. ------------------------ like的用法许多人都是知道的,最为常用的情况就是select * from a where name like '%a%'; 其中'%'代表的是任意个字符,它的效果像是正则表达式里的'*',它有几种用法:'a%','%a%','%a',分别表示以什么开头,存在什么以及以什么结尾. 另外也可以使用'_'字符,这表示一个任意字符.效果类似正则表达式里面的'.'. like是对这个字段里面的所有

Mybatis使用MySQL模糊查询时输入中文检索不到结果怎么办_java

项目开发中,在做Mybatis动态查询时,遇到了一个问题:MySQL在进行LIKE模糊查询时,输入英文可以正常检索出结果,但是输入中文后检索得到的结果为空. 由于是使用GET方式请求,所以为了确保中文不乱码,在控制台接收到请求参数后,对中文进行了一次编码. try { realName = new String(realName.getBytes("GBK"), "UTF-8"); } catch (UnsupportedEncodingException exce