✍️
炼码教程 - SQL 边学边练
  • License
  • 介绍 Introduction
    • 目录 Content
  • Level 1
    • Hello SQL
    • 简单的 SELECT 语句
    • 简单的 INSERT 语句
    • 简单的 UPDATE 语句
    • 简单的 DELETE 语句
  • Level 2
    • 简单的数据库和数据表操作
      • 创建数据库
      • 创建数据表
      • 删除数据表
      • 删除数据库
    • 约束
      • 主键约束
      • 自增长约束
    • 常见数据类型
  • Level 3
    • SELECT进阶
      • WHERE 条件子句
      • ORDER BY 与 LIMIT
      • SELECT DISTINCT
    • Function 函数
      • AVG()
      • COUNT()
      • MAX()
      • MIN()
      • SUM()
      • ROUND()
      • NULL()
  • Level 4
    • Level 4 时间
  • Level 5
    • Level 5 多表单联合
    • 外键
    • 别名
    • 多表联结
      • INNER JOIN
      • LEFT JOIN
      • RIGHT JOIN
      • OUTER JOIN
  • Level 6
    • Level 6 临时表单
    • GROUP BY
    • HAVING
    • 子查询
      • SELECT 语句中的子查询
      • INSERT 语句中的子查询
      • UPDATE 语句中的子查询
      • DELETE 语句中的子查询
      • 多行子查询
      • 多列子查询
      • HAVING 子句中的子查询
      • 内联视图子查询
  • Level 7
    • Level 7 索引
  • Level 8
    • Level 8 事务 Transaction
  • Level 9
    • Level 9 复杂的SQL查询
  • Level MAX
    • Level 10 变量和循环
  • 附录 Appendix
    • 数据类型参考手册
    • 函数 Function
    • 通配符
    • 演示数据库
    • common
    • Bug 001
Powered by GitBook
On this page
  • 1. 比较运算符
  • 1.1 比较运算符实例 Ⅰ
  • 1.2 比较运算符实例 Ⅱ
  • 练习题:比较运算符Ⅰ
  • 练习题:比较运算符 Ⅱ
  • 2. 逻辑运算符 AND、OR和NOT
  • 2.1 逻辑运算符实例 Ⅰ
  • 2.2 逻辑运算符实例 Ⅱ
  • 练习题: 逻辑运算符 Ⅰ
  • 练习题:逻辑运算符 Ⅱ
  • 3. 特殊条件
  • 3.1 IN
  • 3.1.1 IN 实例
  • 练习题:IN Ⅰ
  • 3.2.2 NOT IN 实例
  • 练习题:NOT IN
  • 3.2 BETWEEN AND
  • 练习题:BETWEEN AND
  • 练习题:带有文本值的 BETWEEN
  • 练习题: 带有日期的 BETWEEN 实例
  • 3.3 IS NULL
  • 练习题:IS NUL
  • 3.5 LIKE
  • 练习题:LIKE
  • 4. 总结
  • 练习题:综合

Was this helpful?

  1. Level 3
  2. SELECT进阶

WHERE 条件子句

前面我们已经学习了如何通过SELECT FROM实现简单的查询语句,也了解了当我们希望返回指定查询结果时,可以通过WHERE筛选。

实际上WHERE的功能远比我们前面学习的强大的多,这里我们通过更全面的讲解和练习来帮助你更快速、熟练得掌握WHERE条件字句。

1. 比较运算符

比较运算是指可以使用下列比较运算符比较两个值,当用运算符比较两个值时,结果是一个逻辑值,即成立用真(True)表示,不成立则用假(False)表示

操作符

说明

=

等于,当操作符左右值相等时为真,否则为假

<>

不等于,当操作符左右值不相等时为真,否则为假

<

小于,当左值小于右值为真,否则为假

<=

小于等于,当左值小于等于为真,否则为假

>

大于,左值大于右值为真,否则为假

>=

大于等于,左值大于或等于右值为真,否则为假

WHERE会从数据表中筛选条件子句为真(True)的数据行,并将结果返回并显示。

1.1 比较运算符实例 Ⅰ

lintcode数据库中,课程表courses的列student_count表示学生人数,我们希望查询学生人数超过800的所有课程信息,实现如下

SELECT *
FROM courses
WHERE student_count > 800;

执行输出结果

mysql> SELECT *
    -> FROM courses
    -> WHERE student_count > 800;
+----+-------------------------+-------------------+-------------+------------+
| id | name                    | student_count | created_at | teacher_id |
+----+-------------------------+-------------------+-------------+------------+
|  1 | Senior Algorithm        |               880 | 2020-06-01  |          4 |
|  2 | System Design           |              1350 | 2020-07-18  |          3 |
|  6 | Artificial Intelligence |              1660 | 2018-05-13  |          3 |
| 12 | Dynamic Programming     |              2000 | 2018-08-18  |          1 |
+----+-------------------------+-------------------+-------------+------------+
4 rows in set (0.00 sec)

可以清楚地看出我们返回得到了学生人数超过800的所有课程信息

1.2 比较运算符实例 Ⅱ

lintcode数据库中,课程表courses的列teacher_id表示上课教师的id信息,我们希望查询上课教师id为3的所有课程名称

SELECT name
FROM courses
WHERE teacher_id = 3;

执行输出结果

mysql> SELECT name
    -> FROM courses
    -> WHERE teacher_id = 3;
+-------------------------+
| name                    |
+-------------------------+
| System Design           |
| Django                  |
| Artificial Intelligence |
| Java P6+                |
+-------------------------+
4 rows in set (0.00 sec)

结果可以清楚地看出我们教师id为3的教师一共教授四门课程,课程名称如上所示。

练习题:比较运算符Ⅰ

题目描述:查询教师表teachers中教师年龄大于20岁的所有教师信息

SELECT *
FROM teachers
WHERE age > 20;

目标输出结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE age > 20;
+----+------------------+-------------------------+-----+---------+
| id | name             | email                   | age | country |
+----+------------------+-------------------------+-----+---------+
|  2 | Northern Beggar  | northern.beggar@qq.com  |  21 | CN      |
|  3 | Western Venom    | western.venom@163.com   |  28 | USA     |
|  4 | Southern Emperor | southern.emperor@qq.com |  21 | JP      |
+----+------------------+-------------------------+-----+---------+
3 rows in set (0.00 sec)

练习题:比较运算符 Ⅱ

题目描述:查询教师表teachers中教师国籍为中国(CN)的所有教师名称,注意,teachers表中国籍为大写字母表示

SELECT name
FROM teachers
WHERE country = 'CN';

目标输出结果

mysql> SELECT name
    -> FROM teachers
    -> WHERE country = 'CN';
+-----------------+
| name            |
+-----------------+
| Northern Beggar |
| Linghu Chong    |
+-----------------+
2 rows in set (0.00 sec)

2. 逻辑运算符 AND、OR和NOT

前面我们学习了简单的比较运算符,那么如果我们希望查询上课人数在500到1200之间的所有课程信息,一个条件已经无法满足我们的要求了,我们希望有办法可以将多个条件联立起来,这时就需要用到逻辑运算。

逻辑运算可以使用逻辑运算符将简单的条件语句连接成复杂的条件语句。我们SQL常用的逻辑运算符有AND、OR和NOT,具体使用如下

其中P和Q为条件语句,即结果为真或为假

例如在课程表中:

P 为 “学生人数大于800人”,即表示为 student_count > 800

Q 为 ”学生人数小于1000人“,即表示为 student_count < 1000

例子

逻辑运算符

结果

P AND Q

AND

P和Q都为真时,结果为真,否则为假

P OR Q

OR

P或Q只要有一个为真时,结果为真,否则为假

NOT P

NOT

NOT表示取反操作,即P为真结果为假,P为假结果为真

2.1 逻辑运算符实例 Ⅰ

从数据库lintcode中,查询课程表courses中学生人数student_count在800(包括)和1000(之间)的所有课程信息

SELECT *
FROM courses
WHERE student_count >= 800 and student_count < 1000;

执行输出结果

mysql> SELECT *
    -> FROM courses
    -> WHERE student_count >= 800 and student_count < 1000;
+----+---------------------+-------------------+-------------+------------+
| id | name                | student_count | created_at | teacher_id |
+----+---------------------+-------------------+-------------+------------+
|  1 | Advanced Algorithms |               880 | 2020-06-01  |          4 |
+----+---------------------+-------------------+-------------+------------+
1 row in set (0.00 sec)

可以看到上课学生人数在800(包括)到1000(不包括)的课程只有'Advanced Algorithms'

2.2 逻辑运算符实例 Ⅱ

从数据库lintcode中,查询教师表teachers中除了年龄age在20岁以上(不包括20岁)且来自于中国(CN)的以外所有教师信息

SELECT *
FROM teachers
WHERE NOT (age > 20 AND country = 'CN');

执行输出结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE NOT (age > 20 AND country = 'CN');
+----+------------------+---------------------------+-----+---------+
| id | name             | email                     | age | country |
+----+------------------+---------------------------+-----+---------+
|  1 | Eastern Heretic  | eastern.heretic@gmail.com |  20 | UK      |
|  3 | Western Venom    | western.venom@163.com     |  28 | USA     |
|  4 | Southern Emperor | southern.emperor@qq.com   |  21 | JP      |
|  5 | Linghu Chong     | NULL                      |  18 | CN      |
+----+------------------+---------------------------+-----+---------+
4 rows in set (0.00 sec)

NOT用于对查询结果取反操作,所以我们可以看到查询结果的年纪都在20岁即20岁以下,以及国籍不为中国

练习题: 逻辑运算符 Ⅰ

题目描述:查询课程表,查询开课时间在2020年且5月之前的所有课程名称和开课时间

SELECT name,created_at
FROM courses
WHERE created_at >= '2020-01-01' AND created_at < '2020-05-01';

目标输出结果

mysql> SELECT name,created_at
    -> FROM courses
    -> WHERE created_at >= '2020-01-01' AND created_at < '2020-05-01';
+--------+-------------+
| name   | created_at |
+--------+-------------+
| Django | 2020-02-29  |
| Web    | 2020-04-22  |
+--------+-------------+
2 rows in set (0.00 sec)

练习题:逻辑运算符 Ⅱ

题目描述:查询课程表courses中教师id为4,且上课人数在500以上(不包括500人)的所有课程信息

SELECT *
FROM courses
WHERE teacher_id = 4 AND student_count > 500;

目标输出结果

mysql> SELECT *
    -> FROM courses
    -> WHERE teacher_id = 4 AND student_count > 500;
+----+---------------------+-------------------+-------------+------------+
| id | name                | student_count | created_at | teacher_id |
+----+---------------------+-------------------+-------------+------------+
|  1 | Advanced Algorithms |               880 | 2020-06-01  |          4 |
+----+---------------------+-------------------+-------------+------------+
1 row in set (0.00 sec)

3. 特殊条件

3.1 IN

前面我们的查询条件针对的都是连续值的比较,比如学生人数在500到1000之间,年纪在20到25之间,可是如果我们希望查询教师国籍为中国(CN)或英国(UK)的教师信息,就得写成如下形式

SELECT *
FROM teachers
WHERE country = 'CN' OR country = 'UK';

当查询结果更多时,就会有多个OR连接,这会非常麻烦,现在我们有IN能更方便的解决这一方法

3.1.1 IN 实例

使用IN查询教师国籍为中国(CN)或英国(UK)的所有教师信息

SELECT *
FROM teachers
WHERE country IN ('CN', 'UK');

执行输出结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE country IN ('CN', 'UK');
+----+-----------------+---------------------------+-----+---------+
| id | name            | email                     | age | country |
+----+-----------------+---------------------------+-----+---------+
|  1 | Eastern Heretic | eastern.heretic@gmail.com |  20 | UK      |
|  2 | Northern Beggar | northern.beggar@qq.com    |  21 | CN      |
|  5 | Linghu Chong    | NULL                      |  18 | CN      |
+----+-----------------+---------------------------+-----+---------+
3 rows in set (0.00 sec)

练习题:IN Ⅰ

题目描述:使用IN查询课程表中课程名称为'Web'或'Big Data'的课程,返回其课程名称和学生人数

SELECT name,student_count
FROM courses
WHERE name In ('Web', 'Big Data');

目标输出结果

mysql> SELECT name,student_count
    -> FROM courses
    -> WHERE name In ('Web', 'Big Data');
+----------+-------------------+
| name     | student_count |
+----------+-------------------+
| Web      |               340 |
| Big Data |               700 |
+----------+-------------------+
2 rows in set (0.00 sec)

3.2.2 NOT IN 实例

前面我们已经学习了逻辑运算符,这里的IN也可以与逻辑运算符NOT并用,组成NOT IN,表示不在集合中的所有结果。

我们希望查询教师表teachers获得国籍country不为日本(JP)和美国(USA)的所有教师信息

SELECT *
FROM teachers
WHERE country NOT IN ('JP', 'USA');

执行输出结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE country NOT IN ('JP', 'USA');
+----+-----------------+---------------------------+-----+---------+
| id | name            | email                     | age | country |
+----+-----------------+---------------------------+-----+---------+
|  1 | Eastern Heretic | eastern.heretic@gmail.com |  20 | UK      |
|  2 | Northern Beggar | northern.beggar@qq.com    |  21 | CN      |
|  5 | Linghu Chong    | NULL                      |  18 | CN      |
+----+-----------------+---------------------------+-----+---------+
3 rows in set (0.00 sec)

练习题:NOT IN

题目描述:查询课程表courses中所有teacher_id不为1和3的授课老师所授课程名称

SELECT name
FROM courses
WHERE teacher_id NOT IN (1,3);

目标输出结果

mysql> SELECT name
    -> FROM courses
    -> WHERE teacher_id NOT IN (1,3);
+------------------------+
| name                   |
+------------------------+
| Advanced Algorithms    |
| Web                    |
| Object Oriented Design |
+------------------------+
3 rows in set (0.01 sec)

3.2 BETWEEN AND

BETWEEN AND操作符字如其名,会选取介于两个值之间的数据范围内的值。比如学生人数在300到500之间,我们之前会写student_count > 300 AND student_count < 500,现在我们可以简单写成student_count BETWEEN 300 AND 500。

请注意,在不同的数据库中,BETWEEN 操作符会产生不同的结果!

在某些数据库中,BETWEEN 选取介于两个值之间但不包括两个测试值的字段。

在某些数据库中,BETWEEN 选取介于两个值之间且包括两个测试值的字段。

在某些数据库中,BETWEEN 选取介于两个值之间且包括第一个测试值但不包括最后一个测试值的字段。

因此,请检查您的数据库是如何处理 BETWEEN 操作符!

我们这里选用的是MySQL的支持,BETWEEN 选取介于两个值之间且包括两个测试值的字段,即

BETWEEN 200 AND 250

选取结果会包括200和250

3.2.1 简单的BETWEEN AND 实例

使用BETWEEN AND和IN查询年龄在20到25岁之间( 包括20和25岁 ),但是国籍不为中国和英国的教师信息,注意,BETWEEN AND包括选取的两个值

SELECT *
FROM teachers
WHERE (age BETWEEN 20 AND 25) AND (country NOT IN ('CN','UK'));

执行输出结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE (age BETWEEN 20 AND 25) AND (country NOT IN ('CN','UK'));
+----+------------------+-------------------------+-----+---------+
| id | name             | email                   | age | country |
+----+------------------+-------------------------+-----+---------+
|  4 | Southern Emperor | southern.emperor@qq.com |  21 | JP      |
+----+------------------+-------------------------+-----+---------+
1 row in set (0.00 sec)

注意这里我们AND左右的条件语句加入了括号(),是为了让括号()内的子语句优先计算,得到逻辑值真(True)或假(False),再通过AND比较获得结果。

如果不加括号,则美办法直观得看出应该优先执行哪一部分,因为BETWEEN AND也有AND,会造成混淆从而产生期望以外的结果。

练习题:BETWEEN AND

题目描述:查询课程表courses中学生人数在700到1000之间且教师id为3的所有课程信息

SELECT *
FROM courses
WHERE (student_count BETWEEN 700 AND 1000) AND (teacher_id = 3);

执行输出结果

mysql> SELECT *
    -> FROM courses
    -> WHERE (student_count BETWEEN 700 AND 1000) AND (teacher_id = 3);
+----+----------+-------------------+-------------+------------+
| id | name     | student_count | created_at | teacher_id |
+----+----------+-------------------+-------------+------------+
|  3 | Django   |               780 | 2020-02-29  |          3 |
|  7 | Java P6+ |               780 | 2019-01-19  |          3 |
+----+----------+-------------------+-------------+------------+
2 rows in set (0.00 sec)

3.2.2 NOT BETWEEN 实例

前面我们学习了NOT IN,那么BETWEEN是否可以在前面加上逻辑运算符NOT从而获得相反的操作呢,答案是可行的,这里我们看一下接下来的实例。

从数据库Lintcode的课程表中,查询上课学生人数不在500到1000之间的所有课程

SELECT *
FROM courses
WHERE student_count NOT BETWEEN 500 AND 1000;

执行输出结果

mysql> SELECT *
    -> FROM courses
    -> WHERE student_count NOT BETWEEN 500 AND 1000;
+----+-------------------------+-------------------+-------------+------------+
| id | name                    | student_count | created_at | teacher_id |
+----+-------------------------+-------------------+-------------+------------+
|  2 | System Design           |              1350 | 2020-07-18  |          3 |
|  4 | Web                     |               340 | 2020-04-22  |          4 |
|  6 | Artificial Intelligence |              1660 | 2018-05-13  |          3 |
| 10 | Object Oriented Design  |               300 | 2020-08-08  |          4 |
| 12 | Dynamic Programming     |              2000 | 2018-08-18  |          1 |
+----+-------------------------+-------------------+-------------+------------+
5 rows in set (0.00 sec)

3.2.4 带有文本值的 BETWEEN 实例

前面我们BETWEEN使用的都是数值信息,那么文本信息可否比较呢,比如课程名称为字母组成,如何比较呢?下面我们通过实例来学习下,带有文本值的 BETWEEN实例

选择课程名开始字母在'D'到‘Z'的所有课程名称

SELECT name
FROM courses
WHERE name BETWEEN 'D' AND 'Z';

执行输出结果

mysql> SELECT name
    -> FROM courses
    -> WHERE name BETWEEN 'D' AND 'Z';
+------------------------+
| name                   |
+------------------------+
| System Design          |
| Django                 |
| Web                    |
| Java P6+               |
| Data Analysis          |
| Object Oriented Design |
| Dynamic Programming    |
+------------------------+
7 rows in set (0.00 sec)

这里因为我们输入的是单个字母,所以选取的会是课程名开头字母为'D'到’Z'之间的课程名,那么如果输入为两个字母呢?返回结果如何?

练习题:带有文本值的 BETWEEN

题目描述:查询课程名首两个字母在'Db'和'Dy'之间所有课程的名称

SELECT name
FROM courses
WHERE name BETWEEN 'Db' AND 'Dz';

目标输出结果

mysql> SELECT name
    -> FROM courses
    -> WHERE name BETWEEN 'Db' AND 'Dz';
+---------------------+
| name                |
+---------------------+
| Django              |
| Dynamic Programming |
+---------------------+
2 rows in set (0.00 sec)

可以看到我们会逐个查询课程名称的第一个字母和第二个字母,是否在'D'到'D'以及'b'到‘z'之间(具体的顺序会有差异,我们应该以结果为准)。

3.2.5 带有日期的 BETWEEN 实例

查询课程表中courses中创建课程时间在 '2020-01-10' 和 '2020-05-14' 之间的所有课程信息

SELECT *
FROM courses
WHERE created_at BETWEEN '2020-01-10' AND '2020-05-14';

执行输出结果

mysql> SELECT *
    -> FROM courses
    -> WHERE created_at BETWEEN '2020-01-10' AND '2020-05-14';
+----+--------+-------------------+-------------+------------+
| id | name   | student_count | created_at | teacher_id |
+----+--------+-------------------+-------------+------------+
|  3 | Django |               780 | 2020-02-29  |          3 |
|  4 | Web    |               340 | 2020-04-22  |          4 |
+----+--------+-------------------+-------------+------------+
2 rows in set (0.00 sec)

练习题: 带有日期的 BETWEEN 实例

题目描述:查询开课时间在2020年内,学生人数在500人以上的所有课程信息

SELECT *
FROM courses
WHERE (created_at BETWEEN '2020-01-01' AND '2020-12-30') AND (student_count > 500);

目标输出结果

mysql> SELECT *
    -> FROM courses
    -> WHERE (created_at BETWEEN '2020-01-01' AND '2020-12-30') AND (student_count > 500);
+----+---------------------+-------------------+-------------+------------+
| id | name                | student_count | created_at | teacher_id |
+----+---------------------+-------------------+-------------+------------+
|  1 | Advanced Algorithms |               880 | 2020-06-01  |          4 |
|  2 | System Design       |              1350 | 2020-07-18  |          3 |
|  3 | Django              |               780 | 2020-02-29  |          3 |
|  5 | Big Data            |               700 | 2020-09-11  |          1 |
+----+---------------------+-------------------+-------------+------------+
4 rows in set (0.00 sec)

3.3 IS NULL

NULL 值代表遗漏的未知数据。默认的,表的列可以存放 NULL 值。

如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL 值保存。

NULL 值的处理方式与其他值不同。

NULL 用作未知的或不适用的值的占位符。

注释:无法比较 NULL 和 0;它们是不等价的。

我们查询教师表teachers可以发现

mysql> SELECT * FROM teachers;
+----+------------------+---------------------------+-----+---------+
| id | name             | email                     | age | country |
+----+------------------+---------------------------+-----+---------+
|  1 | Eastern Heretic  | eastern.heretic@gmail.com |  20 | UK      |
|  2 | Northern Beggar  | northern.beggar@qq.com    |  21 | CN      |
|  3 | Western Venom    | western.venom@163.com     |  28 | USA     |
|  4 | Southern Emperor | southern.emperor@qq.com   |  21 | JP      |
|  5 | Linghu Chong     | NULL                      |  18 | CN      |
+----+------------------+---------------------------+-----+---------+
5 rows in set (0.00 sec)

其中id为5的教师,'Linghu Chong'的email信息为空。这意味着如果在 "email" 列插入一条不带值的记录,"email" 列会使用 NULL 值保存。

那么我们如何测试 NULL 值呢?

无法使用比较运算符来测试 NULL 值,比如=、!=或 <>。

我们必须使用 IS NULL 和IS NOT NULL操作符。

3.4.1 IS NULL 实例

查询教师表teachers中,email为空的所有教师信息

SELECT *
FROM teachers
WHERE email IS NULL;

执行输出结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE email IS NULL;
+----+--------------+-------+-----+---------+
| id | name         | email | age | country |
+----+--------------+-------+-----+---------+
|  5 | Linghu Chong | NULL  |  18 | CN      |
+----+--------------+-------+-----+---------+
1 row in set (0.00 sec)

如果我们希望查询教师表中email不为空的所有信息呢? 这时候IS NOT NULL就发挥了作用

SELECT *
FROM teachers
WHERE email IS NOT NULL;

执行输出结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE email IS NOT NULL;
+----+------------------+---------------------------+-----+---------+
| id | name             | email                     | age | country |
+----+------------------+---------------------------+-----+---------+
|  1 | Eastern Heretic  | eastern.heretic@gmail.com |  20 | UK      |
|  2 | Northern Beggar  | northern.beggar@qq.com    |  21 | CN      |
|  3 | Western Venom    | western.venom@163.com     |  28 | USA     |
|  4 | Southern Emperor | southern.emperor@qq.com   |  21 | JP      |
+----+------------------+---------------------------+-----+---------+
4 rows in set (0.00 sec)

可以看到输出结果中email信息为空的教师数据已经被我们筛除。

练习题:IS NUL

题目描述:查询教师表中国籍为’CN'或‘JP’且email信息不为空的所有教师信息

SELECT *
FROM teachers
WHERE (country in ('CN', 'JP')) AND (email IS NOT NULL);

目标输出结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE (country in ('CN', 'JP')) AND (email IS NOT NULL);
+----+------------------+-------------------------+-----+---------+
| id | name             | email                   | age | country |
+----+------------------+-------------------------+-----+---------+
|  2 | Northern Beggar  | northern.beggar@qq.com  |  21 | CN      |
|  4 | Southern Emperor | southern.emperor@qq.com |  21 | JP      |
+----+------------------+-------------------------+-----+---------+
2 rows in set (0.00 sec)

3.5 LIKE

前面我们学习BETWEEN和比较运算符时,都会涉及到文本操作,比如前面课程名称首字母的范围,这种方案虽然可行但是不稳定,不是直接对文本的操作。这里我们学习使用LIKE更准确规范得解决文本比较问题。

Like比较类似我们平时用到的搜索,我们先通过案例学习下功能

3.5.1 LIKE 实例

我希望查询以字母'D'开头的所有课程,用LIKE写法如下

SELECT *
FROM courses
WHERE name LIKE 'D%';

执行输出结果

mysql> SELECT *
    -> FROM courses
    -> WHERE name LIKE 'D%';
+----+---------------------+-------------------+-------------+------------+
| id | name                | student_count | created_at | teacher_id |
+----+---------------------+-------------------+-------------+------------+
|  3 | Django              |               780 | 2020-02-29  |          3 |
|  8 | Data Analysis       |               500 | 2019-07-12  |          1 |
| 12 | Dynamic Programming |              2000 | 2018-08-18  |          1 |
+----+---------------------+-------------------+-------------+------------+
3 rows in set (0.01 sec)

可以看到我们的结果中包括所有课程名以字母'D'开头的课程信息

其中'D%'表示以D开头的所有单词,%表示为通配符,可以替代0个或多个字符

3.5.2 LIKE 总结

SQL中的通配符有以下类型

通配符

描述

%

替代 0 个或多个字符

_

替代一个字符

[charlist]

字符列中的任何单一字符

或 [!charlist]

不在字符列中的任何单一字符

其中

charlist代表字符数列,即类似与[abc]表示字符a、b 、c中的任意一个,[^abc]表示不是字符a

b、c中的其他字符。

常用通配符的示例:

  • LIKE 'AB%' 以 AB 开始的任意字符串;

  • LIKE '%ABC' 以 ABC 结束的任意字符串;

  • LIKE '%ABC%' 含 ABC 的任意字符串;

  • LIKE '_AB' 以 AB 结束,长度为 3 的字符串;

  • LIKE '[ACE]%' 以 A、C、E 中任意一个字符开始的字符串;

  • LIKE 'L[^a]%' 以 L 开始、且第 2 个字符不是 a 的任意字符串。

练习题:LIKE

题目描述:查询教师表teachers中,所有使用qq邮箱的教师名称和邮箱

SELECT name,email
FROM teachers
WHERE email LIKE '%@qq.com';

目标输出结果

mysql> SELECT name,email
    -> FROM teachers
    -> WHERE email LIKE '%@qq.com';
+------------------+-------------------------+
| name             | email                   |
+------------------+-------------------------+
| Northern Beggar  | northern.beggar@qq.com  |
| Southern Emperor | southern.emperor@qq.com |
+------------------+-------------------------+
2 rows in set (0.00 sec)

4. 总结

经过上面实例的学习,我们总结得到WHERE条件子句语法形式如下

语法

SELECT column_name[,column_name]
FROM table_name
WHERE column_name operator value;

其中

table_name指所要查询的表

column_name指所要显示的列名,需要显示多列可以有多个column_name,多个列名用逗号,隔开,也可以全部显示用*表示

value指所需要参与运算的具体值

operator指条件运算符,可以是下面表格中的任意运算符的任意一个

运算符

描述

=

等于

<>

不等于。注释:在 SQL 的一些版本中,该操作符可被写成 !=

>

大于

<

小于

>=

大于等于

<=

小于等于

BETWEEN

在某个范围内

LIKE

搜索某种模式

IN

指定针对某个列的多个可能值

练习题:综合

题目描述:查询教师表中邮箱为腾讯邮箱且国籍为中国的所有教师信息

SELECT *
FROM teachers
WHERE (email LIKE '%@qq.com') AND (country = 'CN');

目标执行结果

mysql> SELECT *
    -> FROM teachers
    -> WHERE (email LIKE '%@qq.com') AND (country = 'CN');
+----+-----------------+------------------------+-----+---------+
| id | name            | email                  | age | country |
+----+-----------------+------------------------+-----+---------+
|  2 | Northern Beggar | northern.beggar@qq.com |  21 | CN      |
+----+-----------------+------------------------+-----+---------+
1 row in set (0.01 sec)
PreviousSELECT进阶NextORDER BY 与 LIMIT

Last updated 4 years ago

Was this helpful?