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 会如何处理连续的 % 通配符。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nginx(Docker 安装的nginx)配置域名SSL证书

1.首先确保Linux环境上已经安装了docker&#xff08;可参考VMware使用和Linux安装Docker_wmware直接部署linux和安装docker后-CSDN博客 2.通过docker 安装nginx&#xff08;可参考Linux 环境安装Nginx—源码和Dokcer-CSDN博客&#xff09; 3.安装SSL证书 3.1 在宿主机中创建…

DaisyDisk for mac 苹果电脑磁盘清理工具

DaisyDisk for Mac是一款直观易用的磁盘空间分析工具&#xff0c;专为Mac用户设计&#xff0c;旨在帮助他们快速识别和管理磁盘上的文件与文件夹&#xff0c;从而释放存储空间。 软件下载&#xff1a;DaisyDisk for mac 激活版 DaisyDisk采用独特的可视化界面&#xff0c;将磁盘…

R语言使用函数随机抽取并求均值和做T检验,最后输出随机抽取50次均值和pvalue的结果

1.输入数据&#xff1a;“5utr-5d做ABD中有RG4和没有RG4的TE之间的T检验.csv” 2.代码&#xff1a; setwd("E:\\R\\Rscripts\\5UTR_extended_TE") # 载入必要的库 library(tidyverse) library(dplyr) library(openxlsx) # 读取数据 data <- read.csv("5ut…

机器学习笔记(4)—逻辑回归(Logistic Regression)

文章目录 逻辑回归&#xff08;Logistic Regression&#xff09;分类问题假说表示判定边界代价函数简化的成本函数和梯度下降多类别分类&#xff1a;一对多 逻辑回归&#xff08;Logistic Regression&#xff09; 分类问题 分类问题中&#xff0c;我们要预测的变量 y y y是一…

第2章 进程与线程(4)

2.4 死锁 多个进程因竞争资源而造成的一种僵局。若无外力,这些进程都无法推进。 2.4.1 死锁的概念 死锁,饥饿,死循环的对比 死锁产生的原因: (1)系统资源的竞争 (2)进程不合理的推进顺序 (3)信号量使用不恰当也会造成死锁 总结:对不可剥夺的资源的不合理分配导致死锁 死锁产…

吴恩达机器学习笔记 二十九 树的增强 XGBoost 极端梯度提升 什么时候使用决策树 决策树和神经网络的比较

增强树&#xff1a;和随机森林类似&#xff0c;但再抽取时每个样本被抽到的概率不是相同的&#xff0c;而是让算法更容易选到使之前训练的树错误分类的样本。这种方式被称为刻意练习(deliberate practice)&#xff0c;相当于把做的不好的部分再拿出来练习一遍。 XGBoost&#x…

基于nodejs+vue文学创作的社交论坛python-flask-django-php

课题主要采用nodejs技术和MySQL数据库技术以及express框架进行开发。系统主要包括个人中心、用户管理、文章类型管理、文章信息管理、文章举报管理、警告信息管理、系统管理等功能&#xff0c;从而实现智能化的社交论坛管理方式&#xff0c;提高社交论坛管理的效率。 前端技术&…

R折线图(自备)

目录 折线图基础 创建散点和折线图 复杂折现加图例 折线图柱状图 数据处理 进行差异检验 基础绘图折线 基础绘图箱线 进行合并 双轴柱状与折线图 数据 折线图基础 创建散点和折线图 rm(list ls()) opar <-par(no.readonlyTRUE)##自带orange数据集 par(mfrowc…

科技引领趋势:3D元宇宙展厅在各行业中的应用及其未来展望

随着技术的不断进步&#xff0c;3D元宇宙展厅正逐渐成为各行各业展示产品的新选择。相较于传统的线下展厅&#xff0c;3D元宇宙展厅以其独特的优势&#xff0c;为产品展示和品牌推广提供了全新的可能性。 一、虚拟与现实的完美融合 3D元宇宙展厅是指在虚拟世界中构建的三维展览…

小程序接入第三方信息流流程 下载SDK

由第三方信息流提供相应的SDK下载链接以及接入说明和开发文档或其他方式接入&#xff0c;如果第三方能支持小程序SDK&#xff0c;则不需要后面步骤&#xff0c;只需要提供相关开发文档和接入方式接口 接入SDK 后台开发人员接入第三方提供的SDK&#xff0c;并进行相关接口开发…

DFS深度优先搜索刷题(二)

一.P1683 入门 算法思想&#xff1a;设置瓷砖状态st&#xff0c;这里瓷砖状态是否走过决定计数与否&#xff0c;因为可以重复走过但只记一次&#xff0c;所以可以不用回溯。每一次dfs都记录此时的坐标与进入可能的新坐标。 const int N 25;int W, H; char map[N][N];//存地图…

二叉树的遍历、存储、性质、定义——数据结构——day7

树的定义 树的定义&#xff1a;树(Tree)是n(n≥0)个结点的有限集。n0 时称为空树。在任意一棵非空树中&#xff1a; (1)有且仅有一个特定的称为根(Root)的结点&#xff1b; (2)当n>1时&#xff0c;其余结点可分为m(m>0)个互不相交的有限集T1、T2、……、Tm,其中每一个集…

可视化图表:折线图,非常简单的一类图表。

一、折线图的作用 折线图是一种常用的可视化图表&#xff0c;主要用于展示数据随时间或其他连续变量的变化趋势。它的作用包括&#xff1a; 变化趋势的展示&#xff1a;折线图可以清晰地展示数据随时间或其他连续变量的变化趋势。通过连接数据点&#xff0c;可以观察到数据的上…

HTTPS 从懵懵懂懂到认知清晰、从深度理解到落地实操

Https 在现代互联网应用中&#xff0c;网上诈骗、垃圾邮件、数据泄露的现象时有发生。为了数据安全&#xff0c;我们都会选择采用https技术。甚至iOS开发调用接口的时候&#xff0c;必须是https接口&#xff0c;才能调用。现在有部分浏览器也开始强制要求网站必须使用https&am…

【jenkins+cmake+svn管理c++项目】创建一个项目

工作台点击"新建item",进入下图&#xff0c;选择Freestyle project,并输入项目名称&#xff0c; 点击确定之后进入项目配置页面&#xff0c;填写描述&#xff0c;然后在下边源码管理部分选择svn, 填写代码的url 上图的Credentials处填写svn的有效登录名和密码&#x…

搭建hive环境,并解决后启动hive命令报 hive: command not found的问题

一、问题解决 1、问题复现 2、解决问题 查阅资料得知该问题大部分是环境变量配置出了问题&#xff0c;我就输入以下命令进入配置文件检查自己的环境变量配置&#xff1a; [rootnode03 ~]# vi /etc/profile 检查发现自己的hive配置没有问题 &#xff0c;于是我就退出&#xf…

吴恩达深度学习笔记:浅层神经网络(Shallow neural networks)3.6-3.8

目录 第一门课&#xff1a;神经网络和深度学习 (Neural Networks and Deep Learning)第三周&#xff1a;浅层神经网络(Shallow neural networks)3.6 激活函数&#xff08;Activation functions&#xff09;3.7 为什么需要非线性激活函数&#xff1f;&#xff08;why need a non…

QT+Opencv+yolov5实现监测

功能说明&#xff1a;使用QTOpencvyolov5实现监测 仓库链接&#xff1a;https://gitee.com/wangyoujie11/qt_yolov5.git git本仓库到本地 一、环境配置 1.opencv配置 将OpenCV-MinGW-Build-OpenCV-4.5.2-x64文件夹放在自己的一个目录下&#xff0c;如我的路径&#xff1a; …

Docker服务

任务描述&#xff1a;请采用podman&#xff0c;实现有守护程序的容器应用。 &#xff08;1&#xff09;在linux2上安装docker-ce&#xff0c;导入rocky镜像。 &#xff08;2&#xff09;创建名称为skills的容器&#xff0c;映射本机的8000端口到容器的80端口&#xff0c;在容…

2月线上速溶咖啡行业数据分析:“减肥咖啡”引领电商新潮流

随着生活节奏的加快&#xff0c;速溶咖啡因其便捷性受到广大消费者的青睐。不过&#xff0c;在如今世界咖啡市场激烈竞争的情况下&#xff0c;中国速溶咖啡市场也受到影响&#xff0c;增速有所放缓。 根据鲸参谋电商数据平台显示&#xff0c;2月线上综合电商&#xff08;京东天…