MySQL WHERE 条件查询

我们通常要求在执行 SELECT 查询时,都要带上查询条件。那这一节,我们就来学习一些简单的 WHERE 条件查询。

我们仍然以技术派文章表 article 为例,比如说我们要查找标题为“聊聊分库分表”的文章,可以这么写:

SELECT * FROM article WHERE title = '聊聊分库分表';

这其中的 WHERE title = '聊聊分库分表' 就是查询条件,title 是字段名,'聊聊分库分表' 是字段值。

比较查询操作符

除了上面提到的 = 操作符,MySQL 还提供了很多其他的比较查询操作符,常用的有以下几种:

比如说,我们要查找 user_id 大于 1000 的文章,可以这么写:


SELECT title, user_id, create_time FROM article WHERE user_id > 1000;

其他的我就不一一展示了,很简单,大家可以自己试试(也没必要 😂,知道有这么一些比较操作符就行了,用到的时候会用就 OK)

区间查询

假如说我们要查询 user_id 在 1000 到 2000 之间的文章,可以这么写:


SELECT title, user_id, create_time FROM article WHERE user_id >= 1000 AND user_id <= 2000;

利用一个 >= 和一个 <=,配合 AND 关键字,就可以实现区间查询。除此之外,MySQL 还提供了 BETWEEN 这个关键字,可以更简洁地实现区间查询(字段 user_id 不需要写两次),比如:

SELECT title, user_id, create_time FROM article WHERE user_id BETWEEN 1000 AND 2000;

配合 NOT 关键字,还可以实现区间查询的取反操作,比如说,我们要查询 user_id 不在 1000 到 2000 之间的文章,可以这么写:

SELECT title, user_id, create_time FROM article WHERE user_id NOT BETWEEN 1000 AND 2000;

枚举查询

假如说我们要查询 user_id 是 1、2、3 的文章,可以这么写:

SELECT title, user_id, create_time FROM article WHERE user_id IN (1, 2, 3);

只要匹配到枚举中的任意一个值,就会被查询出来。

同样配合 NOT 关键字,可以实现枚举查询的取反操作,比如说,我们要查询 user_id 不是 1、2、3 的文章,可以这么写:

SELECT title, user_id, create_time FROM article WHERE user_id NOT IN (1, 2, 3);

NULL 查询

我们提到过,NULL 是一个特殊的值,表示未知或者不存在。

我们没办法直接通过 = 或者 != 来查询 NULL 值,而是要使用 IS NULL 或者 IS NOT NULL 来查询。

这里简单解释一下为什么?(面试可能会被问到)

在 SQL 中,NULL 表示一个未知值或缺失值,它不等于空字符串、零或任何其他值。

由于 NULL 是未知的,所以它与任何其他值(包括另一个 NULL)的比较都是未知的。在逻辑上,你不能说一个未知的值等于或不等于另一个未知的值或任何具体的值。

根据 SQL 标准,任何与 NULL 进行比较的操作结果都是 NULL,表示逻辑上的“未知”。这意味着表达式column = NULL或column != NULL的结果都不是 TRUE 或 FALSE,而是 NULL。

为了解决这个问题,SQL 引入了 IS NULL 和 IS NOT NULL,专门用于检查列是否为 NULL。这些操作符产生的是布尔值(TRUE 或 FALSE),可以直接用在逻辑表达式中。

比如说,我们来查询短标题 short_title 为 NULL 的文章:


SELECT title, short_title, create_time FROM article WHERE short_title IS NULL;

不为 NULL 的文章,可以这么写:


SELECT title, short_title, create_time FROM article WHERE short_title IS NOT NULL;

当然了,为了简化查询,技术派在设计表的时候,尽量避免了使用 NULL,而是使用空字符串或者 0 来代替。

这样,当我们要查询 short_title 不为空的文章时,就可以这么写:


SELECT title, short_title, create_time FROM article WHERE short_title != '';

不然还要在 SQL 层面做一层对前端查询条件的转换,麻烦。

逻辑操作符

除了上面提到的 AND、NOT,MySQL 还提供了 OR、() 等用来改变查询条件的逻辑操作符,它们配合起来还可以用来组合多个查询条件。

AND 操作符

AND 操作符用于组合多个查询条件,只有当所有的条件都满足时,才会返回结果。

比如说,我们要查询 user_id 不等于 1 且标题为“聊聊分库分表”的文章,可以这么写:

SELECT title, user_id, create_time FROM article WHERE user_id != 1 AND title = '聊聊分库分表';

OR 操作符

OR 操作符用于组合多个查询条件,但只要有一个条件满足,就会返回结果。

ADN 和 OR 其实在编程中也是非常常见的,比如说 Java 中的 && 和 ||。



逻辑运算符

比如说,我们要查询 user_id 等于 1 或者标题为“聊聊分库分表”的文章,可以这么写:

SELECT title, user_id, create_time FROM article WHERE user_id = 1 OR title = '聊聊分库分表'

;

优先级操作符

小括号 () 操作符用于改变查询条件的优先级,比如说,我们要查询 user_id 不等于 1 且标题为“聊聊分库分表”或者 short_title 不为空的文章,可以这么写:

SELECT title, user_id, create_time FROM article WHERE user_id != 1 AND (title = '聊聊分库分表' OR short_title != '');

对比一下有小括号和没有小括号的查询结果,是完全不一样的,因为逻辑的先后顺序不同,这个大家都能懂:

通配符查询

有时候,我们并不需要精确查询,模糊查询就够了,那这时候就需要一些通配符来帮我们完成工作 

比如说我们要查询标题中包含“分布式”的文章,可以这么写:


SELECT title, user_id, create_time FROM article WHERE title LIKE '%分布式%';

LIKE 关键字用于模糊查询,之前用到的 = 属于精确查询。

MySQL 支持两种通配符,% 和 _,其中 % 用于匹配任意长度的字符串,_ 用于匹配单个字符。

我们来详细看一下。

% 通配符

% 通配符用于匹配任意长度的字符串,包括零长度,在查询文章标题、用户名等此类字段时,会非常有用。

我们来执行一下之前提到的模糊查询标题带有“分布式”的文章:

% 通配符可以出现在模式的任何位置,比如说,我们要查询标题以“分布式”开头的文章,可以这么写:


SELECT title, user_id, create_time FROM article WHERE title LIKE '分布式%';

也可以出现在模式的开头,表示以该关键词结尾:

SELECT title, user_id, create_time FROM article WHERE title LIKE '%分布式';

不过,还是以出现在模式的两端最常见。我们是通过 MyBatis-Plus 提供的 like 方法来实现模糊查询的,它会自动在关键词两端加上 %。

源码在 SqlUtils 类的 concatLike 方法中,通过判断通配符的位置来拼接通配符 %。

当然了,有些复杂 SQL MyBatis-Plus 也不一定能满足,这时候就需要我们自己写 SQL 了。

通常会在 Mapper.xml 文件中进行 SQL 语句的定义和拼接,比如说技术派的 admin 端在查询文章的时候,就是通过自定义 SQL 来实现模糊查询的。

注意看这行 SQL:

<if test="searchParams.title != null and searchParams.title != ''">and a.title like concat('%', #{searchParams.title}, '%')</if>

如果 searchParams.title 不为空,就会拼接 % 通配符,实现模糊查询。

其中的 concat 方法是 MySQL 的字符串拼接函数。

# 是 MyBatis 中参数占位符的标记,用于预处理语句(PreparedStatement)中,以防止 SQL 注入攻击。当使用#{}来包裹一个参数时,MyBatis 会在执行 SQL 之前将该参数的值安全地填充到 SQL 语句中。

注意,这是一个考点。在面试中,可能会被问到 # 和 $ 的区别。

$ 也是 MyBatis 中参数占位符的标记,用于直接拼接 SQL 语句,不会进行预处理。当使用${}来包裹一个参数时,MyBatis 会直接将该参数的值拼接到 SQL 语句中。

#{} 和 ${} 的区别在于,#{} 是预处理,会对参数进行安全处理,而 ${} 是直接拼接,不会对参数进行处理。

MyBatis 中的 # 和 $

我们这里稍微拓展一丢丢,假如 mapper.xml 文件中的 SQL 语句是这样的:

select * from user where name = #{name};

那么它将被解析为:

select * from user where name = ?;

一个 #{} 会被解析为一个参数占位符 ?。

而如果 xml 中的 SQL 语句是这样的:


select * from user where name = '${name}';

当我们传入的参数是 name = "藏三" 时,它将被解析为:

select * from user where name = '藏三';

$ 会直接拼接参数的值,不会进行预处理。这就存在 SQL 注入的风险。

假如有这样的 SQL 语句:

select * from ${tableName} where name = #{name}

当 tableName 为 user; delete user; -- 时,它将被解析为:

select * from user; delete user; -- where name = ?;

-- 是 SQL 中的注释符,表示注释掉后面的内容。于是,一条本来是 SQL 查询的语句,变成了删除 user 表的语句。

这是万万不能够的,当然了,这里讲的很浅,我们单独留一个传送门(里面再细讲):

连续的%通配符

我们这里来实验一下,假如查询条件中包含 % 通配符,MyBatis 会如何解析呢?MySQL 的执行结果又会怎么样呢?

假如我们要查询标题中包含“%0”的文章

MyBatis

先来看 MyBatis 生成的 SQL 语句:

我把关键的部分摘出来:

Preparing: select a.id from article a where a.title like concat('%', ?, '%') order by a.update_time desc limit ?, ?

Parameters: %0(String), 0(Long), 10(Long)

可以看到,#{}是通过占位符 ? 的方式进行拼接的。

MySQL

那最终 MySQL 执行的 SQL 语句又是什么样的?

我们可以通过打开 MySQL 的通用查询日志(General Query Log)来辅助我们完成这项工作。

  1. 可以通过 SHOW VARIABLES LIKE 'general_log'; 来查看通用查询日志是否开启。ON 为开启,OFF 为关闭。
  2. 可以通过 SHOW VARIABLES LIKE 'general_log_file'; 来查看通用查询日志的文件路径。

如果未开启的话,可以通过 SET GLOBAL general_log = 'ON'; 来开启通用查询日志。

然后执行上面的查询,就可以在通用查询日志中看到 MySQL 执行的 SQL 语句。

可以通过文本工具打开日志文件,拉到最后,就可以找到对应的 SQL 语句。

可以看到,最终 MySQL 执行的 SQL 语句是这样的(省略部分 SQL 内容):

select a.id from article a where a.title like concat('%', '%0', '%') order by a.update_time desc limit 0, 10

执行结果

前面我们讲了,在SQL的LIKE语句中,%是一个通配符,它可以匹配任意数量(包括零个)的字符。

那 MySQL 是如何处理 %%0% 的呢?

它会将连续的%视为一个,因为它们的含义没有变化——仍然是匹配任意长度的字符序列。

  1. 'a.title LIKE '%0%':匹配任何包含0的a.title。
  2. 'a.title LIKE '%%0%':效果同上,多出来的%并不改变匹配模式。
  3. 'a.title LIKE '%%%0%%%':即使更多的%被添加进来,匹配模式仍然相同。

我们来验证一下,查询 %01%、%%01%、%%%01%的结果是完全一样的,都是查询标题中包含“10”的文章。

所以,% 通配符可以连续出现,但是它们的含义是一样的,都是匹配任意长度的字符序列。这也是一个面试的考点,但实际使用中,应该尽量避免这种情况的出现,因为会让不懂的新手产生困惑。

_ 通配符

_ 通配符其实算是一个占位符,比如说我们要查询标题为“分表”、“分库”的文章,可以这么写:

SELECT title, user_id, create_time FROM article WHERE title LIKE '分_';

但它只会匹配一个字符,所以只能匹配“分表”或者“分库”,而不能匹配“分布式”。

假如标题有这么几个:

  1. 分表
  2. 分库
  3. 分布式
  4. MySQL 分库
  5. MySQL 分表

那么,title LIKE '分_' 就只会匹配到“分表”和“分库”,而不会匹配到“分布式”、“MySQL 分库”、“MySQL 分表”。

所以,_ 通配符在实际工作中并不常用。

转义通配符

如果我们要查询的字符串中本身就包含 % 或者 _,那么就需要对它们进行转义,否则会被误认为是通配符。

MySQL 使用 \ 作为转义字符,比如说,我们要查询标题中包含“%分布式%”的文章,可以这么写:

SELECT title, user_id, create_time FROM article WHERE title LIKE '%\%分布式\%%';

小结

这一节,我们学习了一些简单的 WHERE 条件查询,包括比较查询操作符、区间查询、枚举查询、NULL 查询、逻辑操作符、通配符查询等。

其中重点讲了 % 通配符的使用,包括 MyBatis 中的 # 和 $ 的区别,以及 MySQL 会如何处理连续的 % 通配符。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/771653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

echarts做水滴图;解决[echarts] unknown series liquidfill 水球加载问题

一份echarts示例代码&#xff0c;包含水滴图 直接在echarts里使用水滴图liquidfill会报错[echarts] unknown series liquidfill 解决方案&#xff1a;需要下载echarts-liquidfill依赖 echarts-liquidfill2兼容echarts4; echarts-liquidfill3兼容echarts5; 例如&#xff1a;我的…

IDEA使用手册

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

【vue3(七)】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、ref二、TS接口泛型规范1.创建ts文件&#xff0c;定义接口2.引入规范 三、props的使用四、生命周期&#xff08;生命周期函数&#xff0c;生命周期钩子&…

rust中字符串String常用方法和注意事项

Rust 中通常说的字符串指的是&#xff1a;String 和 &str(字符串字面值、或者叫字符串切片)这两种类型。str是rust中基础字符串类型&#xff0c;String是标准库里面的类型。Rust 中的字符串本质上是&#xff1a;Byte的集合&#xff08;Vec<u8>&#xff09; 基础类型…

【第三方登录】Google邮箱

登录谷歌邮箱开发者 https://console.developers.google.com/ 先创建项目 我们用的web应用 设置回调 核心主要&#xff1a; 1.创建应用 2.创建客户端ID 3.设置域名和重定向URL 4.对外公开&#xff0c;这样所有的gmail邮箱 都能参与测试PHP代码实现 引入第三方包 h…

Spring实例化Bean的三种方式

参考资料&#xff1a; Core Technologies 核心技术 spring实例化bean的三种方式 构造器来实例化bean 静态工厂方法实例化bean 非静态工厂方法实例化bean_spring中有参构造器实例化-CSDN博客 1. 构造函数 1.1. 空参构造函数 下面这样表示调用空参构造函数&#xff0c;使用p…

linux查看usb是3.0还是2.0

1 作为device cat /sys/devices/platform/10320000.usb30drd/10320000.dwc3/udc/10320000.dwc3/current_speed 或 /sys/class/udc/10320000.dwc3/current_speed 如下 high-speed usb2.0 super-speed usb3.0 2 作为host linux下使用以下命令查看 &#xff0c;如果显示 速率为…

python关于字符串基础学习

字符串 python字符串是不可改变的 Python不支持单字符类型&#xff0c;单字符也是作为一个字符串使用的。 字符串编码 python3直接支持Unicode,可以表示世界上任何书面语言的字符 python3的字符默认就是16位Unicode编码&#xff0c;ASCII是Unicode的子集 使用内置函数 ord()…

c++初步

作业&#xff1a; 定义自己的命名空间&#xff0c;其中有string类型的变量&#xff0c;再定义两个函数&#xff0c;一个函数完成字符串的输入&#xff0c;一个函数完成求字符串长度&#xff0c;再定义一个全局函数完成对该字符串的反转 #include <iostream> #include &…

辽渤湾海现已加入2024第七届燕窝天然滋补品博览会

参展企业介绍 大连辽渤湾海产品有限公司&#xff0c;是一家主营海参、鲍鱼、海胆等大连海产品的加工和销售的综合型水产企业&#xff0c;拥有国内精良的整条加工流水线&#xff0c;拥有上千平米的现代化加工办公场地的现代化企业。现已发展成为大连海参产品的主导型深加工基地。…

SpringBoot 三种拦截http请求方式Filter,Interceptor和AOP

1 Filter Filter常被叫做过滤器&#xff0c;filter的调用周期大致如下 也就是说filter在servlet之前&#xff0c;没有办法在filter中获取springboot中的java bean对象。 Filter生命周期方法 init:在服务器启动后&#xff0c;会创建Filter对象&#xff0c;然后调用init方法。…

无货源违规又现,现在还能做抖音小店吗?无货源商家该怎么调整?

大家好&#xff0c;我是电商花花。 最近好像又有很多人的店铺被查无货源违规&#xff0c;店铺还被扣12分&#xff0c;也申诉不了。 如果想要长期的做下去&#xff0c;就不要秀那些花里胡哨的操作&#xff0c;也不要为了短暂的自然流量而进行违规操作&#xff0c;为什么你的店…

【网络爬虫】(1) 网络请求,urllib库介绍

各位同学好&#xff0c;今天开始和各位分享一下python网络爬虫技巧&#xff0c;从基本的函数开始&#xff0c;到项目实战。那我们开始吧。 1. 基本概念 这里简单介绍一下后续学习中需要掌握的概念。 &#xff08;1&#xff09;http 和 https 协议。http是超文本传输&#xf…

leetcode mt simple

Leetcode-MT-Simple 文章实际写于2021年&#xff0c;那个炎热的夏天。 Leet Code 美团题库简单类总结&#xff0c;题目按照解法可大致分为数学法、计数法、位运算、双指针法、字符串、哈希表、栈、递归/迭代、排序法、匹配法、记忆化法、二分法、分治法、摩尔投票法、前缀和、…

基于nodejs+vue家装一体化平台python-flask-django-php

提高现下家装一体化平台的准确度&#xff0c;同时降低经济波动带来的不良影响&#xff0c;希望本文能对广大学者的研究提供参考。 前端技术&#xff1a;nodejsvueelementui, Express 框架于Node运行环境的Web框架, 语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&am…

喜获千万元价值补贴,探索 AI 领域新应用:Zilliz 全力支持 AI 初创企业

价值 1000 万元的大额补贴&#xff01;得到领先全行业的向量数据库团队支持&#xff01;尽享独家生态资源&#xff01;「Zilliz AI 初创计划」正式开启&#xff01; 「Zilliz AI 初创计划」是 Zilliz 面向 AI 初创企业推出的一项扶持计划&#xff0c;预计提供总计 1000 万元的 …

书生·浦语大模型实战营——两周带你玩转微调部署评测全链路

引言 人工智能技术的发展日新月异&#xff0c;其中大模型的发展尤其迅速&#xff0c;已然是 AI 时代最炙手可热的当红炸子鸡。 然而&#xff0c;大模型赛道对于小白开发者来说还是有不小的门槛。面对内容质量参差不齐的课程和实际操作中遇到的问题&#xff0c;许多开发者往往…

2核4g服务器能支持多少人访问?阿里云2核4g服务器在线人数

阿里云2核4G服务器多少钱一年&#xff1f;2核4G配置1个月多少钱&#xff1f;2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

【PCL】mac下安装PCL的安装与配置

【PCL】mac下安装PCL的安装与配置 PCL PCL官方文档 PCL&#xff08;Point Cloud Library&#xff09;是在吸收了前人点云相关研究基础上建立起来的大型跨平台开源C编程库&#xff0c;它实现了大量点云相关的通用算法和高效数据结构&#xff0c;涉及到点云获取、滤波、分割、配…

知识图谱推理算法综述(上):基于距离和图传播的模型

背景 知识图谱系统的建设需要工程和算法的紧密配合&#xff0c;在工程层面&#xff0c;去年蚂蚁集团联合 OpenKG 开放知识图谱社区&#xff0c;共同发布了工业级知识图谱语义标准 OpenSPG 并开源&#xff1b;算法层面&#xff0c;蚂蚁从知识融合&#xff0c;知识推理&#xff…