MySQL单表查询

关于对数据库中的数据进行操作,除了之前章节中讲解到的插入、更新和删除,还有一个使用频率更高、更重要的操作就是查询操作。查询是指从数据库中获取所需的数据,使用不同的查询方式可以获取不同的数据。一般将只涉及一张数据表的查询称为单表查询,本章将对单表查询进行讲解。

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的高级查询的内容,点个关注不迷路。

能看到最后的都是最棒的,感谢大家的支持,鄙人感激不尽。

  • 18
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值