内容简介:我们上边介绍的我们需要把这个例子中的
我们上边介绍的 student_info
、 student_score
表中的记录都很少,但是实际应用中的表里可能存储几千万条,甚至上亿条记录。而且我们通常并不是对所有的记录都感兴趣,只是想查询到符合某些条件的那些记录。比如我们只想查询名字为 范剑
的学生基本信息,或者 计算机学院
的学生都有哪些什么的,这些条件也被称为 搜索条件
或者 过滤条件
,当某条记录符合 搜索条件
时,它将被放入结果集中。
简单搜索条件
我们需要把 搜索条件
放在 WHERE
语句中,比如我们想查询 student_info
表中名字是 范剑
的学生的一些信息,可以这么写:
mysql> SELECT number, name, id_number, major FROM student_info WHERE name = '范剑'; +----------+--------+--------------------+-----------------+ | number | name | id_number | major | +----------+--------+--------------------+-----------------+ | 20180105 | 范剑 | 181048199308156368 | 飞行器设计 | +----------+--------+--------------------+-----------------+ 1 row in set (0.01 sec) mysql> 复制代码
这个例子中的 搜索条件
就是 name = '范剑'
,也就是当记录中的 name
列的值是 '范剑'
的时候,该条记录的 number
、 name
、 id_number
、 major
这些字段才可以被放入结果集。像 name = '范剑'
这种 搜索条件
称为精确匹配, =
称为 条件操作符
。我们看 MySQL
中都有哪些简单的条件操作符:
操作符 | 示例 | 描述 |
---|---|---|
= |
a = b |
等于 |
<> 或者 != |
a <> b |
不等于 |
< |
a < b |
小于 |
<= |
a <= b |
不大于 |
> |
a > b |
大于 |
>= |
a >= b |
不小于 |
BETWEEN |
a BETWEEN b AND c |
满足 b <= a <= c |
NOT BETWEEN |
a NOT BETWEEN b AND c |
不满足 b <= a <= c |
我们想查询学号大于 20180103
的学生信息可以这么写:
mysql> SELECT number, name, id_number, major FROM student_info WHERE number > 20180103; +----------+-----------+--------------------+-----------------+ | number | name | id_number | major | +----------+-----------+--------------------+-----------------+ | 20180104 | 史珍香 | 141992199701078600 | 软件工程 | | 20180105 | 范剑 | 181048199308156368 | 飞行器设计 | | 20180106 | 朱逸群 | 197995199501078445 | 电子信息 | +----------+-----------+--------------------+-----------------+ 3 rows in set (0.01 sec) mysql> 复制代码
查询专业不是 计算机科学与工程
的一些学生信息可以这么写:
mysql> SELECT number, name, id_number, major FROM student_info WHERE major != '计算机科学与工程'; +----------+-----------+--------------------+-----------------+ | number | name | id_number | major | +----------+-----------+--------------------+-----------------+ | 20180103 | 范统 | 17156319980116959X | 软件工程 | | 20180104 | 史珍香 | 141992199701078600 | 软件工程 | | 20180105 | 范剑 | 181048199308156368 | 飞行器设计 | | 20180106 | 朱逸群 | 197995199501078445 | 电子信息 | +----------+-----------+--------------------+-----------------+ 4 rows in set (0.00 sec) mysql> 复制代码
需要注意的是 BETWEEN ... AND ...
操作符的使用,它表示一个范围,比方说我们想查找学号在 20180102
~ 20180104
间的学生信息,可以这么写:
mysql> SELECT number, name, id_number, major FROM student_info WHERE number BETWEEN 20180102 AND 20180104; +----------+-----------+--------------------+--------------------------+ | number | name | id_number | major | +----------+-----------+--------------------+--------------------------+ | 20180102 | 杜琦燕 | 151008199801178529 | 计算机科学与工程 | | 20180103 | 范统 | 17156319980116959X | 软件工程 | | 20180104 | 史珍香 | 141992199701078600 | 软件工程 | +----------+-----------+--------------------+--------------------------+ 3 rows in set (0.00 sec) mysql> 复制代码
如果想查询指定范围之外的数据记录,可以使用 NOT BETWEEN ... AND ...
的语法,比如这样:
mysql> SELECT number, name, id_number, major FROM student_info WHERE number NOT BETWEEN 20180102 AND 20180104; +----------+-----------+--------------------+--------------------------+ | number | name | id_number | major | +----------+-----------+--------------------+--------------------------+ | 20180101 | 杜子腾 | 158177199901044792 | 计算机科学与工程 | | 20180105 | 范剑 | 181048199308156368 | 飞行器设计 | | 20180106 | 朱逸群 | 197995199501078445 | 电子信息 | +----------+-----------+--------------------+--------------------------+ 3 rows in set (0.00 sec) mysql> 复制代码
这样就可以查出学号不在 20180102
~ 20180104
这个区间内的所有学生信息。
多值匹配
有时候指定的匹配值并不是单个值,而是一个列表,只要匹配到列表中的某一项就算匹配成功,这种情况可以使用 IN
操作符:
操作符 | 示例 | 描述 |
---|---|---|
IN |
a IN (b1, b2, ...) |
a是b1, b2, ... 中的某一个 |
NOT IN |
a NOT IN (b1, b2, ...) |
a不是b1, b2, ... 中的任意一个 |
比如我们想查询 软件工程
和 飞行器设计
专业的学生信息,可以这么写:
mysql> SELECT number, name, id_number, major FROM student_info WHERE major IN ('软件工程', '飞行器设计'); +----------+-----------+--------------------+-----------------+ | number | name | id_number | major | +----------+-----------+--------------------+-----------------+ | 20180103 | 范统 | 17156319980116959X | 软件工程 | | 20180104 | 史珍香 | 141992199701078600 | 软件工程 | | 20180105 | 范剑 | 181048199308156368 | 飞行器设计 | +----------+-----------+--------------------+-----------------+ 3 rows in set (0.01 sec) mysql> 复制代码
如果想查询不是这两个专业的学生的信息,可以这么写:
mysql> SELECT number, name, id_number, major FROM student_info WHERE major NOT IN ('软件工程', '飞行器设计'); +----------+-----------+--------------------+--------------------------+ | number | name | id_number | major | +----------+-----------+--------------------+--------------------------+ | 20180101 | 杜子腾 | 158177199901044792 | 计算机科学与工程 | | 20180102 | 杜琦燕 | 151008199801178529 | 计算机科学与工程 | | 20180106 | 朱逸群 | 197995199501078445 | 电子信息 | +----------+-----------+--------------------+--------------------------+ 3 rows in set (0.00 sec) mysql> 复制代码
NULL
值检查
我们前边说过, NULL
代表没有值,意味着你并不知道该列应该填入什么数据,在判断某一列是否为 NULL
的时候并不能单纯的使用 =
操作符,而是需要专业判断值是否是 NULL
的操作符:
操作符 | 示例 | 描述 |
---|---|---|
IS NULL |
a IS NULL |
a的值是 NULL |
IS NOT NULL |
a IS NOT NULL |
a的值不是 NULL |
比如我们想看一下 student_info
表的 name
列是 NULL
的学生记录有哪些,可以这么写:
mysql> SELECT number, name, id_number, major FROM student_info WHERE name IS NULL; Empty set (0.00 sec) mysql> 复制代码
由于所有记录的 name
列都不是 NULL
值,所以最后结果是空的,我们看一下查询 name
列不是 NULL
值的方式:
mysql> SELECT number, name, id_number, major FROM student_info WHERE name IS NOT NULL; +----------+-----------+--------------------+--------------------------+ | number | name | id_number | major | +----------+-----------+--------------------+--------------------------+ | 20180101 | 杜子腾 | 158177199901044792 | 计算机科学与工程 | | 20180102 | 杜琦燕 | 151008199801178529 | 计算机科学与工程 | | 20180103 | 范统 | 17156319980116959X | 软件工程 | | 20180104 | 史珍香 | 141992199701078600 | 软件工程 | | 20180105 | 范剑 | 181048199308156368 | 飞行器设计 | | 20180106 | 朱逸群 | 197995199501078445 | 电子信息 | +----------+-----------+--------------------+--------------------------+ 6 rows in set (0.00 sec) mysql> 复制代码
name
列不是 NULL
值的记录就被查询出来啦!
再次强调一遍, 不能直接使用普通的操作符来与 NULL
值进行比较,必须使用 IS NULL
或者 IS NOT NULL
!
多个搜索条件的查询
上边介绍的都是指定单个的搜索条件的查询,我们也可以在一次查询中指定多个搜索条件。
AND操作符
在给定多个搜索条件的时候,我们有时需要某条记录只有在符合所有搜索条件的时候,这条记录才可以被加入到结果集当中,这种情况我们可以使用 AND
操作符来连接多个搜索条件。比如我们想从 student_score
表中找出科目为 '母猪的产后护理'
并且成绩大于 75
分的记录,可以这么写:
mysql> SELECT * FROM student_score WHERE subject = '母猪的产后护理' AND score > 75; +----------+-----------------------+-------+ | number | subject | score | +----------+-----------------------+-------+ | 20180101 | 母猪的产后护理 | 78 | | 20180102 | 母猪的产后护理 | 100 | +----------+-----------------------+-------+ 2 rows in set (0.00 sec) mysql> 复制代码
其中的 subject = '母猪的产后护理'
和 score > 75
是两个搜索条件,我们使用 AND
操作符把这两个搜索条件连接起来表示只有当两个条件都满足的记录才能被加入到结果集。
OR操作符
在给定多个搜索条件的时候,我们有时需要某条记录在符合某一个搜索条件的时候,这条记录就可以被加入到结果集当中,这种情况我们可以使用 OR
操作符来连接多个搜索条件。比如我们想从 student_score
表中找出成绩大于 95
分或者小于 55
分的记录,可以这么写:
mysql> SELECT * FROM student_score WHERE score > 95 OR score < 55; +----------+-----------------------------+-------+ | number | subject | score | +----------+-----------------------------+-------+ | 20180102 | 母猪的产后护理 | 100 | | 20180102 | 论萨达姆的战争准备 | 98 | | 20180104 | 论萨达姆的战争准备 | 46 | +----------+-----------------------------+-------+ 3 rows in set (0.00 sec) mysql> 复制代码
更复杂的搜索条件的组合
如果我们需要在某个查询中指定很多的搜索条件,比方说我们想从 student_score
表中找出课程为 '论萨达姆的战争准备'
,并且成绩大于 95
分或者小于 55
分的记录,那我们可能会这么写:
mysql> SELECT * FROM student_score WHERE score > 95 OR score < 55 AND subject = '论萨达姆的战争准备'; +----------+-----------------------------+-------+ | number | subject | score | +----------+-----------------------------+-------+ | 20180102 | 母猪的产后护理 | 100 | | 20180102 | 论萨达姆的战争准备 | 98 | | 20180104 | 论萨达姆的战争准备 | 46 | +----------+-----------------------------+-------+ 3 rows in set (0.00 sec) mysql> 复制代码
为什么结果中仍然会有 '母猪的产后护理'
课程的记录呢?因为: AND操作符的优先级默认高于OR操作符,也就是说在判断某条记录是否符合条件时会先执行AND操作符两边的搜索条件 。所以
score > 95 OR score < 55 AND subject = '论萨达姆的战争准备' 复制代码
可以被看作下边这两个条件中任一条件成立则整个式子成立:
score > 95 score < 55 AND subject = '论萨达姆的战争准备'
因为结果集中 subject
是 '母猪的产后护理'
的记录中 score
值为 100
,符合第1个条件,所以整条记录会被加到结果集中。为了避免这种尴尬,在一个查询中有多个搜索条件时最好使用小括号 ()
来显式的指定各个搜索条件的执行顺序,比如上边的例子可以写成下边这样:
mysql> SELECT * FROM student_score WHERE (score > 95 OR score < 55) AND subject = '论萨达姆的战争准备'; +----------+-----------------------------+-------+ | number | subject | score | +----------+-----------------------------+-------+ | 20180102 | 论萨达姆的战争准备 | 98 | | 20180104 | 论萨达姆的战争准备 | 46 | +----------+-----------------------------+-------+ 2 rows in set (0.00 sec) mysql> 复制代码
通配符
有时候我们并不能精确的描述我们要查询的东西,比方说我们只是想看看姓 '杜'
的学生信息,而不能精确的描述出这些姓 '杜'
的同学的完整姓名,我们称这种查询为 模糊查询
。 MySQL
中使用下边这两个操作符来支持 模糊查询
:
操作符 | 示例 | 描述 |
---|---|---|
LIKE |
a LIKE b |
a匹配b |
NOT LIKE |
a NOT LIKE b |
a不匹配b |
既然我们不能完整描述要查询的信息,那就用某个符号来替代这些模糊的信息,这个符号就被称为 通配符
。 MySQL
中支持下边这两个 通配符
:
-
%
:代表任意一个字符串。比方说我们想查询
student_info
表中name
以'杜'
开头的记录,我们可以这样写:mysql> SELECT number, name, id_number, major FROM student_info WHERE name LIKE '杜%'; +----------+-----------+--------------------+--------------------------+ | number | name | id_number | major | +----------+-----------+--------------------+--------------------------+ | 20180101 | 杜子腾 | 158177199901044792 | 计算机科学与工程 | | 20180102 | 杜琦燕 | 151008199801178529 | 计算机科学与工程 | +----------+-----------+--------------------+--------------------------+ 2 rows in set (0.00 sec) mysql> 复制代码
或者我们只知道学生名字里边包含了一个
'香'
字,那我们可以这么查:mysql> SELECT number, name, id_number, major FROM student_info WHERE name LIKE '%香%'; +----------+-----------+--------------------+--------------+ | number | name | id_number | major | +----------+-----------+--------------------+--------------+ | 20180104 | 史珍香 | 141992199701078600 | 软件工程 | +----------+-----------+--------------------+--------------+ 1 row in set (0.00 sec) mysql> 复制代码
-
_
:代表任意一个字符。有的时候我们知道要查询的字符串中有多少个字符,而使用
%
时匹配的范围太大,我们就可以用_
来做通配符。就像是支付宝的万能福卡,一张万能福卡能且只能代表任意一张福卡(也就是它不能代表多张福卡)。比方说我们想查询姓
'范'
,并且姓名只有2个字符的记录,可以这么写:mysql> SELECT number, name, id_number, major FROM student_info WHERE name LIKE '范_'; +----------+--------+--------------------+-----------------+ | number | name | id_number | major | +----------+--------+--------------------+-----------------+ | 20180103 | 范统 | 17156319980116959X | 软件工程 | | 20180105 | 范剑 | 181048199308156368 | 飞行器设计 | +----------+--------+--------------------+-----------------+ 2 rows in set (0.00 sec) mysql> 复制代码
不过下边这个查询却什么都没有查到:
mysql> SELECT number, name, id_number, major FROM student_info WHERE name LIKE '杜_'; Empty set (0.00 sec) mysql> 复制代码
这是因为一个
_
只能代表一个字符(%
是代表任意一个字符串),并且student_info
表中并没有姓'杜'
并且姓名长度是2个字符的记录,所以这么写是查不出东西的。
转义通配符
如果我们匹配的字符串中就包含普通字符 '%'
或者 '_'
该咋办,怎么区分它是一个通配符还是一个普通字符呢?
答:如果匹配字符串中需要普通字符 '%'
或者 '_'
的话,需要在它们前边加一个反斜杠 \
以和通配符区分开来:
-
'\%'
代表普通字符'%'
-
'\_'
代表普通字符'_'
比方说这样:
mysql> SELECT number, name, id_number, major FROM student_info WHERE name LIKE '范\_'; Empty set (0.00 sec) mysql> 复制代码
由于 student_info
表中没有叫 范_
的学生,所以查询结果为空。
注意事项
使用通配符时需要特别注意一下, 通配符不能代表 NULL
,如果需要匹配 NULL
的话,需要使用 IS NULL
或者 IS NOT NULL
!
小册
本系列专栏都是 MySQL 入门知识,想看进阶知识可以到小册中查看: MySQL是怎样运行的链接 。小册的内容主要是从小白的角度出发,用比较通俗的语言讲解关于MySQL内核的一些核心概念,比如记录、索引、页面、表空间、查询优化、事务和锁等,总共的字数大约是三四十万字,配有上百幅原创插图。主要是想降低普通 程序员 学习MySQL内核的难度,让学习曲线更平滑一点~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
高性能MySQL
施瓦茨 (Baron Schwartz)、扎伊采夫 (Peter Zaitsev)、特卡琴科 (Vadim Tkachenko) / 宁海元、周振兴、彭立勋、翟卫祥,刘辉 / 电子工业出版社 / 2013-5-1 / 128.00元
《高性能mysql(第3版)》是mysql 领域的经典之作,拥有广泛的影响力。第3 版更新了大量的内容,不但涵盖了最新mysql 5.5版本的新特性,也讲述了关于固态盘、高可扩展性设计和云计算环境下的数据库相关的新内容,原有的基准测试和性能优化部分也做了大量的扩展和补充。全书共分为16 章和6 个附录,内容涵盖mysql 架构和历史,基准测试和性能剖析,数据库软硬件性能优化,复制、备份和恢复,高可......一起来看看 《高性能MySQL》 这本书的介绍吧!