每日一课 | SQL模糊查找

article/2025/8/31 2:43:26

07.

SQL模糊查找

大家好,我是小C,上期给大家分享——通过查询条件实现数据过滤(完结篇)

本期分享内容:SQL模糊查找

本期小C邀请的是董旭阳老师(资深数据库架构师)为我们分享《SQL从入门到精通》专栏。

S  Q  L

使用SQL语句进行模糊查找

前两篇我们介绍了如何利用 WHERE 子句中的查询条件过滤数据,包括比较运算符、逻辑运算符以及空值判断等。同时,我们也提到了 LIKE 运算符可以用于字符串的模糊查找。本篇我们就来讨论一下 SQL 中的模糊匹配。

当需要查找的信息不太确定时,例如只记住了某个员工姓名的一部分,可以使用模糊查找的功能进行搜索。SQL 提供了两种模糊匹配的方法:LIKE 运算符和正则表达式函数。

LIKE 运算符

下面的语句查找姓名以“赵”开头的员工:

SELECT emp_id, emp_name, sexFROM employeeWHERE emp_name LIKE '赵%';

该语句使用了一个新的运算符:LIKE。LIKE 用于指定一个模式,并且返回匹配该模式的数据。该语句的结果如下:

LIKE 运算符支持两个通配符,用于指定模式:

  • %,百分号可以匹配零个或者多个任意字符。

  • _,下划线可以匹配一个任意字符。

以下是一些模式和匹配的字符串:

  • LIKE 'en%',匹配以“en”开始的字符串,例如“english languages”、“end”;

  • LIKE '%en%',匹配包含“en”的字符串,例如“length”、“when are you”;

  • LIKE '%en',匹配以“en”结束的字符串,例如“ten”、“when”;

  • LIKE 'Be_',匹配以“Be”开始,再加上一个任意字符的字符串。例如“Bed”、“Bet”;

  • LIKE '_e%',匹配一个任意字符加上“e”开始的字符串,例如“her”、“year”。

当我们不确定员工邮箱中某个字符的时候,例如“dengzh*@shuguo.com”(其中星号的内容不确定),可以通过模糊匹配进行查找:

SELECT emp_name, emailFROM employeeWHERE email LIKE 'dengzh_@shuguo.com';emp_name|email |
--------|------------------|
邓芝 |dengzhi@shuguo.com|

模式中的下划线匹配了字符“i”。

如果想要执行相反的操作,返回不匹配某个模式的数据,可以使用 NOT LIKE 运算符。以下查询将会返回除了“邓芝”之外的所有员工:

SELECT emp_name, emailFROM employeeWHERE email NOT LIKE 'dengzh_@shuguo.com';

该语句执行的结果如下(显示部分内容):

“%”和“_”是 LIKE 运算符中的通配符。如果需要查找的内容自身包含了“%”或者“_”时,例如想要知道哪些数据包含了“10%”(百分之十,而不是以 10 开始的字符串),应该如何指定模式呢?这种情况需要用到转义字符(escape character)。

转义字符

转义字符可以将通配符“%”和“_”进行转义,将它们当作普通字符使用。默认的转义字符为反斜杠(\)。因此,LIKE 运算符的完整语法如下:

expression LIKE pattern [ ESCAPE 'escape_character' ];

我们来看一个具体的示例就比较容易理解了。首先创建一个测试表:

CREATE TABLE t_like(c1 VARCHAR(20));
INSERT INTO t_like(c1) VALUES ('进度:25% 已完成');
INSERT INTO t_like(c1) VALUES ('日期:2019 年 5 月 25 日');

表 t_like 只有一个字段 c1,类型为字符串;表中包含两条记录。现在需要查找包含“25%”的数据,其中百分号是要查找的内容而不是任意多个字符。以下语句利用转义字符进行查找:

-- 查询包含字符串 25% 的数据
SELECT c1FROM t_likeWHERE c1 LIKE '%25\%%';
-- WHERE c1 LIKE '%25#%%' ESCAPE '#'; -- 指定 # 作为转义字符c1 |
----------|
进度:25% 已完成|

第一个 % 匹配多个任意字符;第二个 % 前面增加了转义字符(\),表示匹配一个百分号;第三个 % 匹配多个任意字符。查询结果中只有一条满足结果的数据,如果去掉转义字符(\)将会返回两条记录。另外,也可以通过 ESCAPE 指定其他的转义字符。

SQL Server 支持更多的通配符:’[ad]’ 匹配 ‘a’ 和 ‘d’;’[a-d]’ 匹配 ‘a’ 、‘b’、‘c’ 和 ‘d’;’[^ad]’ 匹配除了 ‘a’ 和 ‘d’ 之外的其他字符。

在使用 LIKE 查找数据时,还需要注意的一个问题就是大小写。

大小写匹配

对于汉字,不需要区分大小写;但是英文字母却有大小写之分,“A”和“a”是两个不同的字符。不过,4 种数据库对此采取了不同的处理方式:

  • Oracle 和 PostgreSQL 默认区分 LIKE 中的大小写,PostgreSQL 提供了不区分大小写的 ILIKE 运算符;

  • MySQL 和 SQL Server 默认不区分 LIKE 中的大小写。

我们使用大写字母查找员工的电子邮箱:

SELECT emp_name, emailFROM employeeWHERE email LIKE 'M%';emp_name|email |
--------|----------------|
马岱 |madai@shuguo.com|
糜竺 |mizhu@shuguo.com|

以上查询在 Oracle 和 PostgreSQL 中没有返回结果,在 MySQL 和 SQL Server 中返回 2 条结果。你用的是哪个数据库,有没有返回结果?

当我们需要匹配更复杂的模式时,例如判断用户输入的电子邮箱是否合法,无法通过 LIKE 运算符实现。这个时候,需要使用更加强大的正则表达式(Regular Expression)。

正则表达式

正则表达式用于检索或者替换符合某个模式(规则)的文本。很多的编程语言和编辑工具都提供了正则表达式搜索和替换,下图是文本编辑器 Notepad++ 提供的正则表达式查找功能。

我们主要关注如何在 SQL 中使用正则表达式进行高级搜索,但不会介绍正则表达式的细节。如果想要学习正则表达式,可以参考 GitHub 上的正则表达式教程。

我们考虑一个 Web 开发中常见的问题:如何验证用户输入的邮箱地址是否合法?

首先,需要确认合法电子邮箱的规则。以下是一个简单的规则:

  • 以字母或者数字开头;

  • 后面是一个或者多个字母、数组或特殊字符( . _ - );

  • 然后是一个 @ 字符;

  • 之后包含一个或者多个字母、数组或特殊字符( . - );

  • 最后是域名,即 . 以及 2 到 4 个字母。

以上规则使用正则表达式可以表示为:

^[a-zA-Z0-9]+[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$

其中,^ 匹配字符串的开头;[a-zA-Z0-9] 匹配大小写字母或数字;+ 表示匹配前面的内容一次或多次;. 匹配任何一个字符,\. 匹配点号自身;{2,4} 匹配前面的内容 2 次到 4次;$ 匹配字符串的结束。

我们创建一个示例表并生成一些数据,然后查找表中的合法邮箱地址:

CREATE TABLE t_regexp (email VARCHAR(50)
);INSERT INTO t_regexp VALUES ('TEST@shuguo.com');
INSERT INTO t_regexp VALUES ('test@shuguo');
INSERT INTO t_regexp VALUES ('.123@shuguo.com');
INSERT INTO t_regexp VALUES ('test+email@shuguo.cn');
INSERT INTO t_regexp VALUES ('me.me@ shuguo.com');
INSERT INTO t_regexp VALUES ('123.test@shuguo-sanguo.org');

Oracle 和 MySQL 支持类似的正则表达式函数:

REGEXP_LIKE(source_str, pattern [, match_type])

其中,source_str 是被搜索的字符串;pattern 指定匹配的模式,使用正则表达式描述;match_type 指定可选的匹配方式,例如 i 表示不区分大小写,c 表示区分大小写。以下是用于查找合法邮箱地址的语句:

-- MySQL 实现
SELECT emailFROM t_regexpWHERE REGEXP_LIKE(email, '^[a-zA-Z0-9]+[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$');email |
--------------------------|
TEST@shuguo.com |
123.test@shuguo-sanguo.org|-- Oracle 实现
SELECT emailFROM t_regexpWHERE REGEXP_LIKE(email, '^[a-zA-Z0-9]+[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$');EMAIL |
--------------------------|
TEST@shuguo.com |
123.test@shuguo-sanguo.org|

以上查询返回了两个合法的邮箱地址。其中的区别在于,MySQL 中的转义字符需要使用两个反斜线(\)。

PostgreSQL 中提供了正则表达式匹配的运算符(~):

-- PostgreSQL 实现
SELECT emailFROM t_regexpWHERE email ~ '^[a-zA-Z0-9]+[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$';email |
--------------------------|
TEST@shuguo.com |
123.test@shuguo-sanguo.org|

以上查询同样返回了两条合法的邮箱地址。另外,PostgreSQL 还支持以下运算符:

  • ~* 匹配某个正则表达式,不区分大小写;

  • !~ 不匹配某个正则表达式,区分大小写;

  • !~* 不匹配某个正则表达式,不区分大小写。

SQL Server 中没有提供相关的正则表达式函数或者运算符。

小结

SQL 支持使用模式匹配对文本内容进行模糊查找,主要的方式有两种:LIKE 运算符和正则表达式函数或运算符。其中,LIKE 运算符通用性更好,但是需要注意区分大小写的问题;正则表达式函数功能更加强大,但是依赖于不同数据库的实现。

思考题:如果将本节中的邮箱验证模式改为 ^[a-z0-9]+[a-z0-9._-]+@[a-z0-9.-]+\.[a-z]{2,4}$,也就是去掉了正则表达式中的大写字母 A-Z,如何确保仍然能够匹配大写形式的邮箱地址?

今日内容有get吗,欢迎各位留言讨论!

以上,咱们《SQL从入门到精通》七天专栏打卡就结束了,如需了解更多,小伙伴们可识别下方二维码,订阅专栏,咱们下期专栏见!

了解更多详情

可识别下方二维码


http://chatgpt.dhexx.cn/article/av6wf4m2.shtml

相关文章

设置 MYSQL 数据库编码为 utf8mb4

utf-8编码可能2个字节、3个字节、4个字节的字符,但是MySQL的utf8编码只支持3字节的数据,而移动端的表情数据是4个字节的字符。如果直接往采用utf-8编码的数据库中插入表情数据,java程序中将报SQL异常: java.sql.SQLException: Inc…

utf8mb4 字符集(4字节 UTF-8 Unicode 编码)

最近做项目遇到APP评论中有 emoji 表情符号,结果导致插入 MySQL 数据库失败,找到 MySQL 官方相关内容,这里斗胆翻译一下。在翻译过程中有些不明白的地方,如BMP、collation等,都找到官方文档,给出了链接&…

UTF-8编码详解

1.ASCII编码 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所 以,一个字节能表示的最大的…

mysql中的utf8与utf8mb4

一、如何设置utf8mb4 mysql中针对字符串类型,在设置charset的时候可以精确到字段。 如果只将某个字段设置utf8mb4,那么其他字段不会受影响。 如果针对表来设置,那么已经存在的字段依然是utf8,并且会多出utf8的标记,…

What is UTF-8?

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程 UTF-8 is a variable-width character encoding standard that uses between one and four eight-bit bytes to re…

图解unicode、utf8和utf8mb4

字符集和字符编码 字符集(CCS: Coded Character Set): 就是一个表格,表示每个字符对应数字(通常用16进制表示),比如unicode字符集中,数字1对应的就是U00031,字母a对应的…

UTF-8

UTF-8编码规则 UTF-8是Unicode的一种实现方式,也就是它的字节结构有特殊要求,所以我们说一个汉字的范围是0X4E00到0x9FA5,是指unicode值,至于放在utf-8的编码里去就是由三个字节来组织,所以可以看出unicode是给出一个…

MySQL 数据库字符集 utf8 和 utf8mb4 的区别

MySQL 的 utf8 实际上不是真正的 UTF-8。utf8 只支持每个字符最多三个字节,而真正的 UTF-8 是每个字符最多四个字节。 MySQL 一直没有修复这个 bug,他们在 2010 年发布了一个叫作 utf8mb4 的字符集, 绕过了这个问题。当然,他们并…

utf8和utf8mb4的区别

1. 基础知识 1.1 bit , byte , word 字 word 字节 byte (B) 位 bit (b) 1.2 单位换算 1字节 8位(1 byte 8bit) 1字 2字节(1 word 2 byte) 一个汉字 2字节 中文标点 三个字节 一个英文字母 一个字节 英文标点 一个字节 Em…

简单明了!utf8和utf8mb4的区别

一、简介 MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。utf8mb4是utf8 的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用u…

浅谈uf8mb4字符集

要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集(mb4就是most bytes 4的意思,专门用来兼容四字节的unicode),但只有 5.5.3 版本以后的才支持。 为了获取更好的兼容性,应该总是使用 utf…

学习笔记4-K均值聚类算法

K-均值聚类的一般流程 (1)收集数据:可以使用任何方法收集数据 (2)准备数据:需要数值型数据来计算距离,也可以将标称型数据映射为二值型数据再用于距离计算 (3)分析数据…

【吴恩达机器学习-笔记整理】k-means(k-均值聚类算法)

目录: 🌵🌵🌵前言一、应用二、k-means1、参数:2、过程3、应用4、优化目标5、随机初始化6、聚类数量的选择 ❤️❤️❤️忙碌的敲代码也不要忘了浪漫鸭! 🌵🌵🌵前言 ✨你好…

25.K-均值算法的介绍及实现过程

主要内容 K-均值算法的介绍K-均值算法的实现过程K-均值算法的具体例子实现过程 一、K-均值算法的介绍 K-均值(K- means) ** 是最普及的聚类算法**,算法接受一个未标记的数据集,然后将数据聚类成不同的组 聚类算法 是无监督学习…

K-means(K均值聚类算法)算法笔记

K-means(K均值聚类算法)算法笔记 K-means 算法,是比较简单的无监督的算法,通过设定好初始的类别k,然后不断循环迭代,将给定的数据自动分为K个类别。事实上,大家都知道K-means是怎么算的&#x…

K-近邻算法讲解以及实战

1.概述 邻近算法,或者说K最近邻(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。Cover和Hart在1968年提出了最初的…

第十五课.K均值算法

目录 K均值算法原理K均值算法的改进:K-meansnumpy实现K-means K均值算法原理 K均值(K-means)算法属于无监督学习中的聚类算法;聚类是根据样本特征向量之间的相似度或距离,将样本数据划分为若干个样本子集,…

K均值与K近邻算法简析

回顾了一下机器学习的简单算法。 原文链接:https://blog.csdn.net/zll0927/article/details/17000675 K-Means介绍 K-means算法是聚类分析中使用最广泛的算法之一。它把n个对象根据他们的属性分为k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度…

聚类算法、无监督学习、K均值算法及其优化函数

聚类算法 无监督学习:将无标签样本分为不同的两类或者多类,称为聚类算法 K均值算法 K均值算法是一个迭代算法,共两个步骤 1.簇分配:遍历图中每个样本,根据每个样本点离那个聚类中心近,从而将该样本点分配…

K-means算法-综合整理

A 主要流程 a 随机初始化k个点作为簇质心 b 计算每个点与质心距离(常用欧式距离和余弦距离),并将其分配给最近 的质心对应的簇中 c 重新计算每个簇的质心,更新为所有点的平均值 d 反复迭代b-c步骤,直到达到某个终止条…