关于对数据库中的数据进行操作,除了之前章节中讲解到的插入、更新和删除,还有一个使用频率更高、更重要的操作就是查询操作。查询是指从数据库中获取所需的数据,使用不同的查询方式可以获取不同的数据。一般将只涉及一张数据表的查询称为单表查询,本章将对单表查询进行讲解。
SELECT语句
从数据表中查询数据的基本语句是SELECT语句,该语句的基本语法格式如下。
SELECT [DISTINCT] * | 字段名 FROM 数据表名 WHERE 条件表达式;
其中DISTINCT是可选项,用于剔除执行结果中重复的数据
通配符*是所有字段的简写方式,它代表表中的所有字段,*和字段名只能任选其一,选择字段名的话就是查询这个字段的内容,*是查询所有字段的内容。
因为SELECT语句涉及的内容太多,一下子都放到前面怕大家不理解,所以上面的语法格式只有一个简单的WHERE条件表达式,后面会对其他的进行讲解的。
简单查询
查询所有字段
查询所有字段是指返回数据表中符合条件的所有字段的值。查询所有字段的方式有两种,分别为列出所有字段名称进行查询和使用通配符*进行查询,接下来将对这两种方式进行讲解。
1.列出所有字段名称进行查询
在SELECT语句中列出所有字段名称进行查询的基本语法格式如下:
SELECT 字段名1,字段名2,字段名3,...... FROM 数据表名;
mysql> show tables;
+----------------+
| Tables_in_data |
+----------------+
| class |
| class01 |
| class02 |
| data01 |
| dept01 |
| tb_emp01 |
+----------------+
6 rows in set (0.01 sec)
大家可以看到我的这个数据库中有许多个数据表,但里面都是没有数据的,因为前几章给大家演示删除语句的时候数据都删除完了,所以需要写插入数据,就向data01表中插入数据吧:
先使用DESC语句查看数据表的基本结构:
mysql> desc data01;
+-------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------+------+-----+---------+-------+
| age | int | YES | | NULL | |
| id | int | YES | | NULL | |
+-------+------+------+-----+---------+-------+
2 rows in set (0.00 sec)
再插入数据:
mysql> INSERT INTO data01 VALUES
-> (18,1),
-> (20,2);
从执行结果来看这个数据表有两个字段,那么我们就用这两个字段来查询表中的数据:
mysql> SELECT age,id FROM data01;
+------+------+
| age | id |
+------+------+
| 18 | 1 |
| 20 | 2 |
+------+------+
2 rows in set (0.00 sec)
查询语句执行成功。
要注意字段的放置顺序不一样,其执行结果的顺序也是不一样的:
mysql> SELECT id,age FROM data01;
+------+------+
| id | age |
+------+------+
| 1 | 18 |
| 2 | 20 |
+------+------+
2 rows in set (0.00 sec)
我把id字段放到了前面,那么先查询的就是id字段。
2.使用通配符*进行查询
基本语法格式:
SELECT * FROM 数据表名;
还是data01表中的数据,具体语法及执行结果如下:
mysql> SELECT * FROM data01;
+------+------+
| age | id |
+------+------+
| 18 | 1 |
| 20 | 2 |
+------+------+
2 rows in set (0.00 sec)
从执行结果来看通配符*依然顺利的查询出了表中字段的所有数据,这种方式简单,但执行结果只能按照字段在表中的定义顺序排序。
查询指定字段
查询数据时,有时不需要查询所有字段的信息。例如,公司制定一项新的规约,需要查询出所有在职人员的名单并让员工签字确认,此时只需要查询员工的姓名即可。
查询指定字段可以在SELECT语句的字段列表中指定要查询的字段,其语法格式如下。
SELECT 字段名1,字段名2,... FROM 数据表名;
例如我们想要查询data01表中的age字段,具体SQL语句及执行结果如下:
mysql> SELECT age FROM data01;
+------+
| age |
+------+
| 18 |
| 20 |
+------+
2 rows in set (0.00 sec)
从执行结果来看只查询了age字段里面的数据内容。
查询去重数据
数据表的字段如果没有设置唯一约束,那么该字段就可能存储重复的值。有时需要将结果中的重复值去除后进行展示,例如人力资源部门想要获取一份历年的优秀员工名单,考虑有的员工可能多次获得优秀员工,此时需要将查询到的重复姓名去重后展示。MySQL中提供了DISTINCT关键字,可以在查询时去除重复的值,基本语法格式如下。
SELECT DISTINCT 字段名 FROM 数据表名;
在上面的语法格式中,字段名表示要去除重复值的字段名称。
为了更好的演示这个语句,我又创建了一个员工表,具体内容如下:
mysql> SELECT * FROM emp;
+------+--------+
| id | ename |
+------+--------+
| 9452 | 小六 |
| 9542 | 张三 |
| 9594 | 李四 |
| 9745 | 王五 |
| 9835 | 张三 |
+------+--------+
5 rows in set (0.00 sec)
可以看到表中有两个张三,下面使用去重语句查询ename字段:
mysql> SELECT DISTINCT ename FROM emp;
+--------+
| ename |
+--------+
| 小六 |
| 张三 |
| 李四 |
| 王五 |
+--------+
4 rows in set (0.00 sec)
本来有五条数据,两个张三,现在只有四条数据,一个张三,说明我们去重成功了。
DISTINCT也可以作用于多个字段。但要注意,如果有多个关键字的话,那就必须使得这几个关键字的所有内容都一样才会去重。
条件查询
在MySQL中,如果需要有条件的从数据表中查询数据,可以使用WHERE关键字来指定查询条件。查询条件可以是带比较运算符的查询,也可以是带逻辑运算符的查询条件,接下来对基于这两种查询的条件进行讲解。
1.带比较运算符的查询
MySQL提供了一系列的比较运算符,在查询数据时,可以使用比较运算符对数据进行过滤。MySQL常见的比较运算符如下:
= 比较运算符左右两侧的操作数是否相等
<> 比较运算符左右两侧的操作数是否不相等
!= 比较运算符左右两侧的操作数是否不相等
< 比较运算符左侧的数是否小于右侧的数
<= 比较运算符左侧的数是否小于或等于右侧的数
> 比较运算符左侧的数是否大于右侧的数
>= 比较运算符左侧的数是否大于或等于右侧的数
BETWEEN...AND... 比较数据是否存在于指定范围内
IN 比较数据是否存在于指定集合内
IS NULL 比较数据是否为空
IS NOT NULL 比较数据是否不为空
LIKE 通配符匹配,获取匹配到的数据
大家应该对上面的运算符或多或少都有点熟悉吧,有许多都是我们经常用的。
1.带=运算符的查询
=运算符用于比较运算符左右两边的操作数,如果操作数的字段类型为字符串,则需要使用单引号对操作数进行包裹。在WHERE子句的条件表达式中,字符串以不区分大小写的方式进行比较运算。
例如想要查询员工表emp中员工李四的信息,具体SQL语句及执行结果如下:
mysql> SELECT * FROM emp WHERE ename='李四';
+------+--------+
| id | ename |
+------+--------+
| 9594 | 李四 |
+------+--------+
1 row in set (0.00 sec)
由执行结果可知,SELECT语句按要求查询出员工张三的信息。
2.带<>运算符的查询
<>运算符和!=运算符都用于比较操作数是否不相等。例如,技术人员想要使用SQL语句查询员工表中所属部门编号不是9542的员工信息,可以在查询时使用<> 运算符对部门编号(这里部门编号是id字段)进行比较,具体SQL语句及执行结果如下。
mysql> SELECT * FROM emp WHERE id <> 9542;
+------+--------+
| id | ename |
+------+--------+
| 9452 | 小六 |
| 9594 | 李四 |
| 9745 | 王五 |
| 9835 | 张三 |
+------+--------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM emp WHERE id != 9542;
+------+--------+
| id | ename |
+------+--------+
| 9452 | 小六 |
| 9594 | 李四 |
| 9745 | 王五 |
| 9835 | 张三 |
+------+--------+
4 rows in set (0.00 sec)
由执行结果可知,SELECT语句按要求查询出所属部门编号不是9542的员工信息。需要注意的是,NULL不能使用<>运算符和!=运算符进行比较。
3.带<、<=、>、>=运算符的查询
<运算符用于判断左侧操作数是否小于右侧操作数。
例如查询员工编号小于9594编号的员工信息:
mysql> SELECT * FROM emp WHERE id < 9594;
+------+--------+
| id | ename |
+------+--------+
| 9452 | 小六 |
| 9542 | 张三 |
+------+--------+
2 rows in set (0.00 sec)
由执行结果可知,SELECT语句按照要求查询出编号小于9594员工的信息。
<=运算符查询
也就比小于多了一条相等的数据:
mysql> SELECT * FROM emp WHERE id <= 9594;
+------+--------+
| id | ename |
+------+--------+
| 9452 | 小六 |
| 9542 | 张三 |
| 9594 | 李四 |
+------+--------+
3 rows in set (0.00 sec)
>运算符查询:
例如查询员工编号大于9452的员工的信息:
mysql> SELECT * FROM emp WHERE id > 9452;
+------+--------+
| id | ename |
+------+--------+
| 9542 | 张三 |
| 9594 | 李四 |
| 9745 | 王五 |
| 9835 | 张三 |
+------+--------+
4 rows in set (0.00 sec)
>=运算符查询:
mysql> SELECT * FROM emp WHERE id >= 9452;
+------+--------+
| id | ename |
+------+--------+
| 9452 | 小六 |
| 9542 | 张三 |
| 9594 | 李四 |
| 9745 | 王五 |
| 9835 | 张三 |
+------+--------+
5 rows in set (0.00 sec)
相信这些对大家来说都是小菜一碟。
4.带IN运算符的查询
IN运算符用于判断某个值是否在指定集合中,如果值存在集合中,则满足条件,IN运算符语法格式如下:
SELECT *| 字段名1,字段名2,... FROM 数据表名 WHERE IN | NOT IN (元素1,元素2);
既然知道IN了,那NOT IN 猜也能猜出来了吧,就是不在指定集合中的数据。
现在来查询员工编号在9542和9700中的数据:
mysql> SELECT * FROM emp WHERE id IN(9542,9745);
+------+--------+
| id | ename |
+------+--------+
| 9542 | 张三 |
| 9745 | 王五 |
+------+--------+
2 rows in set (0.00 sec)
注意这个是指定集合,是指定的,具体的数,而不是一个范围,所以只能查到两条数据。而且IN()里面的数字是数据表中存在的,如果不存在则查询结果为空:
mysql> SELECT * FROM emp WHERE id IN(9500,9700);
Empty set (0.00 sec)
NOT IN运算符我就不演示了,感兴趣的可以自己实践一下。
6.带IS NULL运算符的查询
当操作数为NULL时,不能使用运算符=、<>、!=进行比较,这是因为NULL代表未指定或不可预知的值。如果需要判断数据是否为NULL,可以使用IS NULL进行比较。
例如,技术人员想要使用SQL语句查询员工表中直属上级编号为NULL的员工信息,可以在查询时使用IS NULL运算符对直属上级编号进行比较,具体SQL语句及执行结果如下。
mysql> SELECT * FROM emp WHERE id IS NULL;
Empty set (0.00 sec)
因为我们没有设置员工编号为空的员工,因此结果是空集。
IS NOT NULL 我也不演示了,自己去动手实践。
7.带LIKE运算符的查询
在查询数据时,有时需要对数据进行模糊查询,例如查询emp表中ename字段的值以字符a开头的记录。为实现这种查询,MySQL提供了LIKE关键字。LIKE 关键字用于比较两个操作数是否匹配。使用LIKE关键字的SELECT语句的语法格式如下。
SELECT* | (字段名1,字段名2,···) FROM 数据表名 WHERE 值 [NOT] LIKE "匹配的字符串";
在上面的语法格式中,NOT是可选项,表示查询与指定字符串不匹配的记录。“匹配的字符串”是用来和值进行匹配的字符串必须使用单引号或双引号进行包裹。
使用LIKE进行字符串的匹配时,匹配的字符串可以是确定的,也可以是模糊的。换句话说,LIKE后面紧跟的匹配的字符串可以是一个普通字符串,也可以是不确是的字符串。当匹配的字符串不确定时,可以使用通配符代替一个或多个真正的字符。LIKE关键字支持的通配符有两个,分别是百分号(%)和下画线(_)。下面分别讲解这两个通配符在LIKE查询中的使用。
(1)%通配符。
%通配符是模糊查询最常用的通配符,它可以匹配任意长度的字符串,包括空字符串。例如,字符串c%可以匹配所有以字符c开始的任意长度的字符串,如c、cu.cut等。
下面进行案例演示:
假如我们要在员工表中查找所有以李开头的员工的信息,那么我们可以在查询的时使用%通配符对员工姓名进行匹配,具体SQL语法及执行结果如下:
mysql> SELECT * FROM emp WHERE ename LIKE '李%';
+------+--------+
| id | ename |
+------+--------+
| 9594 | 李四 |
+------+--------+
1 row in set (0.00 sec)
这个语句使用LIKE进行模糊查询,'李%'表示以李开头匹配任意长度的字符串的员工姓名。
%通配符可以出现在匹配字符串的任意位置。技术人员想要使用SQL语句查询员工表中姓名以“丰”结尾且以“张”开头的员工信息,具体SQL语句及括的如下。
mysql> SELECT * FROM emp WHERE ename LIKE '张%丰';
+------+-----------+
| id | ename |
+------+-----------+
| 9756 | 张三丰 |
+------+-----------+
1 row in set (0.00 sec)
上面的语句是模糊匹配了张三丰中间的‘’三‘’字,如果还有其他的字也是可以匹配出来的,只要开头是张,结尾是丰,中间是什么字无所谓,这就是%通配符的作用,也可以理解为占位。
在使用LIKE模糊查询时还可以使用多个%,例如想要查看员工表中姓名包含三字的员工信息,具体SQL语句及执行结果如下:
mysql> SELECT * FROM emp WHERE ename LIKE '%三%';
+------+-----------+
| id | ename |
+------+-----------+
| 9542 | 张三 |
| 9756 | 张三丰 |
| 9835 | 张三 |
+------+-----------+
3 rows in set (0.00 sec)
在上面的SELECT语句中,使用LIKE进行模糊查询,字符“三”左右两边都使用%通配符为任意长度的字符串占位,表示查询包含三的字符串,因为%也可以匹配空字符串,因此两个字的名字在匹配第三个字的时候会匹配空字符串,因此也会查询到。
(2)_通配符
_通配符也叫下划线,_通配符用于匹配单个字符串,如果需要匹配多个字符串,需要使用多个_通配符,每个_通配符代表一个字符。例如,字符串cu_可以匹配以字符串cu_开始,长度为3的字符串,如cut、cup等;字符串c_l匹配在字符c和字符l之间包含这两个字符的字符串,如cool、coal等。需要注意的是,空格字符也是一个字符,例如,通配字符串 "M__QL"能匹配字符串"MySQL",而不能匹配字符串My SQL。如果使用多个连续的下划线匹配多个连续的字符,下划线之间不能有空格。
例如,想要使用SQL语句查询员工表中姓名长度为3且以字符王开头的员工信息,具体SQL语句及执行结果如下:
mysql> SELECT * FROM emp WHERE ename LIKE '王__';
Empty set (0.00 sec)
结果是空,因为我们的员工没有姓王的三个字符的,这里的_只能匹配一个字符,而%是匹配任意字符,不要搞混了。
三位的没有,那两位的呢:
mysql> SELECT * FROM emp WHERE ename LIKE '王_';
+------+--------+
| id | ename |
+------+--------+
| 9745 | 王五 |
+------+--------+
1 row in set (0.00 sec)
结果显示是有的,那说明查询成功了。
2.带逻辑运算符的查询
NOT、!:逻辑非,返回和操作数相反的结果
AND、&&:逻辑与,操作数全部为真,则结果为1,否则结果为0
OR、||:逻辑或,操作数只要有一个为真,则结果为1,反之结果为0
接下来。通过一些例子来了解这些逻辑运算符在条件查询中的使用。
1.带NOT运算符的查询
运算符NOT和!都表示逻辑非,返回和操作数相反的结果。例如,想要查看员工编号不是9452的员工的信息,具体SQL语句及执行结果如下:
mysql> SELECT * FROM emp WHERE id NOT IN(9452);
+------+-----------+
| id | ename |
+------+-----------+
| 9542 | 张三 |
| 9594 | 李四 |
| 9745 | 王五 |
| 9756 | 张三丰 |
| 9835 | 张三 |
+------+-----------+
5 rows in set (0.00 sec)
mysql> SELECT * FROM emp WHERE id != 9452;
+------+-----------+
| id | ename |
+------+-----------+
| 9542 | 张三 |
| 9594 | 李四 |
| 9745 | 王五 |
| 9756 | 张三丰 |
| 9835 | 张三 |
+------+-----------+
5 rows in set (0.00 sec)
NOT和!代表的意思都是一样的,但用法有点区别,NOT一般和IN连用,!一般和=连用。
2.带AND运算符的查询
在使用SELECT语句查询数据时,有时为了使执行结果更精确,可以使用多个查询条件。在MySQL中,可以使用AND运算符连接两个或多个查询条件,只有满足所有条件的记录才会被返回。带AND运算符的查询语法格式如下。
SELECT *|(字段名1,字段名2,…) FROM 表名 WHERE 条件表达式1 AND条件表达式2...AND条件表达式n;
从上面的语法格式可以看到,在WHERE关键字后面跟了多个条件表达式,条件表达式之间用AND运算符连接。
使用AND连接多个条件表达式时,查询出的数据需要满足所有条件表达式的结果。例如,想要使用SQL语句查询员工表中员工为张三且所属编号为9835的员工信息。可以在查询时使用AND运算符对这两个条件进行连接,具体SQL语句及执行结果如下。
mysql> SELECT * FROM emp WHERE id=9835 AND ename='张三';
+------+--------+
| id | ename |
+------+--------+
| 9835 | 张三 |
+------+--------+
1 row in set (0.00 sec)
由执行结果可知,SELECT语句按要求查询出员工为张三且所属编号为9835的员工信息.
除此之外,AND运算符还可以结合BETWEEN运算符判断某个字段的值是否在指定的范围之内。如果字段的值在指定范围内,则字段的值将被查询出来,反之则不会被查询出来。结合使用BETWEEN和AND进行查询的语法格式如下。
SELECT *|(字段名1,字段名2,···) FROM 数据表名 WHERE 字段名[NOT] BETWEEN 值1 AND 值2;
在上述语法格式中,值1表示范围条件的起始值,值2表示范围条件的结束值。NOT是可选项,表示查询指定范围之外的记录,通常情况下值1需要小于值2,否则查询不到任何结果。
例如,想要查看员工编号在9594到9756之前的员工信息,可以在查询时结合使用BETWEEN和AND关键字对员工编号指定范围,具体SQL语句及执行结果如下;
mysql> SELECT * FROM emp WHERE id BETWEEN 9594 AND 9756;
+------+-----------+
| id | ename |
+------+-----------+
| 9594 | 李四 |
| 9745 | 王五 |
| 9756 | 张三丰 |
+------+-----------+
3 rows in set (0.00 sec)
从结果来看,SELECT语句按要求查询出员工编号在9594到9756之前的员工信息。
如果想查询指定范围之外的记录,可以使用NOT关键字。例如,技术人员想要使用SQL语句查询员工表中员工编号不是9594-9756的员工信息,具体SQL语句及执会结果如下。
mysql> SELECT * FROM emp WHERE id NOT BETWEEN 9594 AND 9756;
+------+--------+
| id | ename |
+------+--------+
| 9452 | 小六 |
| 9542 | 张三 |
| 9835 | 张三 |
+------+--------+
3 rows in set (0.00 sec)
从执行结果看出,查询出来的记录中id的值都是小于9594或者大于9756的。
3.带OR运算符的查询。
在使用SELECT语句查询数据时,可以使用OR运算符连接多个查询条件。与AND运算符不同,在使用OR运算符查询时,只要满足任意一个查询条件,对应的数据就会被查询出来。带OR运算符的查询语法格式如下。
SELECT*[字段名1,字段名2,...] FROM 数据表名 WHERE 条件表达式1 OR条件表达式2 [..OR条件表达式n];
从上述语法格式中可以看到,WHERE子句中可以有多个条件表达式,多个条件表达式之间用OR运算符分隔。
例如,想要使用SQL语句查询员工表中员工为李四或者所属编号为9542的员工信息。在查询时可以使用OR运算符连接这两个条件,具体SQL语句及执行结果如下。
mysql> SELECT * FROM emp WHERE ename='李四' OR id=9542;
+------+--------+
| id | ename |
+------+--------+
| 9542 | 张三 |
| 9594 | 李四 |
+------+--------+
2 rows in set (0.00 sec)
结果查询到两条数据,这是因为OR是只要符合一个条件就可以了,两个条件都符合也可以。
mysql> SELECT * FROM emp WHERE ename='李四' OR id=9999;
+------+--------+
| id | ename |
+------+--------+
| 9594 | 李四 |
+------+--------+
1 row in set (0.00 sec)
在咱们数据表中的员工编号是没有9999这个编号的,但是有李四这个员工,因此只出现了一条数据,这是符合一个条件的情况。
下篇文章会讲MySQL的高级查询的内容,点个关注不迷路。
能看到最后的都是最棒的,感谢大家的支持,鄙人感激不尽。