Java
MySQL
Python
大数据
前端
黑科技
    首页 > 互联网 > MySQL > mysql基本查询MySQL WHERE查询MySQL不等于条件表达式范围查询指定集合

mysql基本查询MySQL WHERE查询MySQL不等于条件表达式范围查询指定集合

[导读]:# 查询 ## 基本查询 MySQL中使用*SELECT*关键字来实现查询.*SELECT*的完整语法如下 ```mysql SELECT 属性列表 FROM 表名或者视图列表(数据源) [WHERE 条件表达式] [GROUP BY 分组] [HAVING 筛选条件表达式...
# 查询
 
## 基本查询
 
MySQL中使用*SELECT*关键字来实现查询.*SELECT*的完整语法如下
 
```mysql
SELECT 属性列表 FROM 表名或者视图列表(数据源) 
[WHERE 条件表达式] 
[GROUP BY 分组] [HAVING 筛选条件表达式] 
[ORDER BY 排序字段][ASC|DESC] 
[LIMIT X OFFSET Y]
```
 
### 没有任何条件的查询语句
 
```mysql
mysql> select * from stu;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
+-----+--------+------+
4 rows in set (0.03 sec)
 
mysql> select sid,sname,sage from stu;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
+-----+--------+------+
4 rows in set (0.00 sec)
```
 
### 带有别名的查询
 
通过as关键字给字段起个名字.一般as是省略的.别名机制用的比较多的地方是夺标查询或者自连接查询.
 
```mysql
mysql> select sid as "学生编号", sname as "学生姓名", sage as "学生年龄" from stu;
+--------------+--------------+--------------+
| 学生编号     | 学生姓名     | 学生年龄     |
+--------------+--------------+--------------+
|            1 | 张三         |           20 |
|            2 | 李四         |           20 |
|            3 | 王五         |           19 |
|            4 | 赵六         |           19 |
+--------------+--------------+--------------+
4 rows in set (0.00 sec)
 
mysql> select sid "学生编号", sname "学生姓名", sage "学生年龄" from stu;
+--------------+--------------+--------------+
| 学生编号     | 学生姓名     | 学生年龄     |
+--------------+--------------+--------------+
|            1 | 张三         |           20 |
|            2 | 李四         |           20 |
|            3 | 王五         |           19 |
|            4 | 赵六         |           19 |
+--------------+--------------+--------------+
4 rows in set (0.00 sec)
 
mysql>
```
 
## 查询子句
 
### WHERE子句
 
where所起到的作用是对From的结果进行筛选.比如下面的语句执行顺序是
 
```mysql
select id ,name,age from student where age > 18;
```
 
- From Student         从Student表中获取表中的所有数据
- Where Age > 18     对From所拿到的结果进行筛选只选择那些Age大于18的
- Select id,namge,age  按照Select的要求把Where筛选过的数据中id字段,name字段和age字段的值交给Select.
 
```mysql
# 当前表中有数据
mysql> select * from stu;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
+-----+--------+------+
4 rows in set (0.00 sec)
 
# 对其进行条件查询 比如要求获取所有年龄大于19岁的
mysql> select sid,sname,sage from stu where 1=1;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
+-----+--------+------+
4 rows in set (0.00 sec)
 
mysql> select sid,sname,sage from stu where sage > 19;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
+-----+--------+------+
2 rows in set (0.00 sec)
 
mysql> select sid,sname,sage from stu where sage > 20;
Empty set (0.00 sec)
 
# 下面是mysql中不等于的写法!
mysql> select sid,sname,sage from stu where 1!=1;
Empty set (0.00 sec)
 
mysql> select sid,sname,sage from stu where 1<>1;
Empty set (0.00 sec)
 
mysql>
 
```
 
#### 查询条件表达式
 
|   查询条件   |         符号或关键字          |
| :----------: | :---------------------------: |
|     比较     |    =、<、>、>=、<=、<>、!=    |
|   指定范围   | between and 、not between and |
|   指定集合   |          in、not in           |
|   匹配字符   |        like、not like         |
| 判断是否为空 |                               |
| 多个条件查询 |   and(且)、or(或)、not(非)    |
 
#### 范围查询
 
```mysql
mysql> select * FROM stu where sid between 4 and 7;
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   4 | 赵六   |   20 | 男      |
|   5 | 孙七   |   17 | 女      |
|   6 | 周八   |   20 | 女      |
|   7 | 吴九   |   21 | 女      |
+-----+--------+------+---------+
4 rows in set (0.00 sec)
 
mysql> select * FROM stu where sid not between 4 and 7;
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
|   2 | 李四   |   18 | 男      |
|   3 | 王五   |   19 | 男      |
|   8 | 郑十   |   19 | 女      |
|   9 | 刘一   |   18 | 女      |
|  10 | 陈二   |   20 | 女      |
+-----+--------+------+---------+
6 rows in set (0.00 sec)
 
mysql>
```
 
#### 指定集合
 
```mysql
mysql> select * FROM stu where sgender in ('男');
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
|   2 | 李四   |   18 | 男      |
|   3 | 王五   |   19 | 男      |
|   4 | 赵六   |   20 | 男      |
+-----+--------+------+---------+
4 rows in set (0.02 sec)
 
mysql> select * FROM stu where sgender not in ('男');
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   5 | 孙七   |   17 | 女      |
|   6 | 周八   |   20 | 女      |
|   7 | 吴九   |   21 | 女      |
|   8 | 郑十   |   19 | 女      |
|   9 | 刘一   |   18 | 女      |
|  10 | 陈二   |   20 | 女      |
+-----+--------+------+---------+
6 rows in set (0.00 sec)
 
mysql> select * FROM stu where sage not in (17,18);
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   3 | 王五   |   19 | 男      |
|   4 | 赵六   |   20 | 男      |
|   6 | 周八   |   20 | 女      |
|   7 | 吴九   |   21 | 女      |
|   8 | 郑十   |   19 | 女      |
|  10 | 陈二   |   20 | 女      |
+-----+--------+------+---------+
6 rows in set (0.02 sec)
 
mysql> select * FROM stu where sage in (17,18);
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
|   2 | 李四   |   18 | 男      |
|   5 | 孙七   |   17 | 女      |
|   9 | 刘一   |   18 | 女      |
+-----+--------+------+---------+
4 rows in set (0.00 sec)
 
mysql> select * FROM stu where sage in (17,18,30);
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
|   2 | 李四   |   18 | 男      |
|   5 | 孙七   |   17 | 女      |
|   9 | 刘一   |   18 | 女      |
+-----+--------+------+---------+
4 rows in set (0.00 sec)
 
mysql>
```
 
#### 匹配字符
 
> ​ 可以做到模糊查询
 
在MySQL中有占位符两个
 
- _  只代表一个字符
- %  代表任意字符
 
```mysql
mysql> select * from stu where sname like '张%';
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   1 | 张三      |   17 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
+-----+-----------+------+---------+
3 rows in set (0.00 sec)
 
mysql> select * from stu where sname like '张_';
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
+-----+--------+------+---------+
1 row in set (0.00 sec)
 
mysql> select * from stu where sname like '张?';
Empty set (0.00 sec)
 
mysql> select * from stu where sname like '张_';
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
+-----+--------+------+---------+
1 row in set (0.00 sec)
 
mysql> select * from stu where sname like '%王%';
+-----+---------+------+---------+
| sid | sname   | sage | sgender |
+-----+---------+------+---------+
|   3 | 王五    |   19 | 男      |
|  16 | 王晶    |   29 | 男      |
|  17 | Jack王  |   30 | 男      |
+-----+---------+------+---------+
3 rows in set (0.00 sec)
 
mysql> select * from stu where sname like '_王%';
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|  18 | 大王   |   30 | 男      |
+-----+--------+------+---------+
1 row in set (0.00 sec)
 
mysql>
```
 
#### 多条件查询
 
```mysql
mysql> select * from stu where sname like '%李%' and sgender = '男';
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   2 | 李四   |   18 | 男      |
|  15 | 李安   |   35 | 男      |
+-----+--------+------+---------+
2 rows in set (0.00 sec)
 
mysql> select * from stu where sname like '%李%' and sgender = '女';
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|  14 | 李娜   |   21 | 女      |
+-----+--------+------+---------+
1 row in set (0.00 sec)
 
mysql> select * from stu where sname like '%李%' or sgender = '女';
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   2 | 李四      |   18 | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 女      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
+-----+-----------+------+---------+
11 rows in set (0.00 sec)
 
mysql> select * from stu where sname like '%李%' or not sgender = '女';
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   1 | 张三      |   17 | 男      |
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   4 | 赵六      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
10 rows in set (0.00 sec)
 
mysql>
 
 
```
 
#### 判断 是否为空值
 
```mysql
mysql> select * from stu;
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   1 | 张三      |   17 | 男      |
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   4 | 赵六      | NULL | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 |         |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
18 rows in set (0.00 sec)
 
mysql> select * from stu where sname is null;
Empty set (0.00 sec)
 
mysql> select * from stu where sage is null;
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   4 | 赵六   | NULL | 男      |
+-----+--------+------+---------+
1 row in set (0.00 sec)
 
mysql> select * from stu where sgender is null;
Empty set (0.00 sec)
 
mysql> select * from stu where sgender = '';
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|  10 | 陈二   |   20 |         |
+-----+--------+------+---------+
1 row in set (0.00 sec)
 
mysql> select * from stu where sage is not null;
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   1 | 张三      |   17 | 男      |
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 |         |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
17 rows in set (0.00 sec)
 
mysql>
 
```
 
 
 
 
 
 
 
### ORDER BY子句
 
> ​ 排序子句
 
我们可以通过Order By利用一个或多个字段对所获取的数据进行排序.排序的方式有两种:降序和升序.默认是升序关键字ASC.降序的关键字是DESC.
 
```mysql
# ASC默认不写.代表升序
mysql> select sid,sname,sage from stu order by sage ;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
+-----+--------+------+
4 rows in set (0.00 sec)
 
# 当然也可以写出来
mysql> select sid,sname,sage from stu order by sage asc;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
+-----+--------+------+
4 rows in set (0.00 sec)
 
# DESC代表降序
mysql> select sid,sname,sage from stu order by sage desc;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
+-----+--------+------+
4 rows in set (0.00 sec)
 
mysql>
 
 
```
 
#### 多条件排序
 
```mysql
# 只有年龄升序
mysql> select sid,sname,sage from stu order by sage asc;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
+-----+--------+------+
4 rows in set (0.00 sec)
 
# 先按照年龄升序,再按照编号降序
mysql> select sid,sname,sage from stu order by sage asc,sid desc;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   4 | 赵六   |   19 |
|   3 | 王五   |   19 |
|   2 | 李四   |   20 |
|   1 | 张三   |   20 |
+-----+--------+------+
4 rows in set (0.00 sec)
 
mysql>
 
 
```
 
### LIMIT 语句
 
> ​ 在Web中用于分页开发.MySQL的特有关键字
 
Limit的用法很简单.比如只想要前三条数据
 
```mysql
mysql> select sid,sname,sage from stu;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
+-----+--------+------+
4 rows in set (0.00 sec)
 
# 只选择前三条
mysql> select sid,sname,sage from stu limit 3;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
|   3 | 王五   |   19 |
+-----+--------+------+
3 rows in set (0.00 sec)
 
# 向后偏移一条数据.选取2条数据.
mysql> select sid,sname,sage from stu limit 1,2;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   2 | 李四   |   20 |
|   3 | 王五   |   19 |
+-----+--------+------+
2 rows in set (0.00 sec)
 
# 向后偏移0行数据.选择2行数据
mysql> select sid,sname,sage from stu limit 0,2;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   1 | 张三   |   20 |
|   2 | 李四   |   20 |
+-----+--------+------+
2 rows in set (0.00 sec)
 
# 向后偏移2行数据.选择2行数据
mysql> select sid,sname,sage from stu limit 2,2;
+-----+--------+------+
| sid | sname  | sage |
+-----+--------+------+
|   3 | 王五   |   19 |
|   4 | 赵六   |   19 |
+-----+--------+------+
2 rows in set (0.00 sec)
 
mysql>
 
```
 
### GROUP BY子句
 
#### 聚合函数
 
MySQL提供了内置函数,常用于统计分析的几个函数也被叫做聚合函数,有以下几个
 
- 求数量 count
- 求最大值 max
- 求最小值 min
- 求平均值 avg
- 求和 sum
 
```mysql
# 想要准确的统计要通过*或者主键
mysql> select count(*) from stu;
+----------+
| count(*) |
+----------+
|       18 |
+----------+
1 row in set (0.05 sec)
 
# 因为有个age的值是空
mysql> select count(sage) from stu;
+-------------+
| count(sage) |
+-------------+
|          17 |
+-------------+
1 row in set (0.02 sec)
 
mysql> select max(sage) from stu;
+-----------+
| max(sage) |
+-----------+
|        35 |
+-----------+
1 row in set (0.00 sec)
 
mysql> select min(sage) from stu;
+-----------+
| min(sage) |
+-----------+
|        17 |
+-----------+
1 row in set (0.00 sec)
 
mysql> select sum(sage) from stu;
+-----------+
| sum(sage) |
+-----------+
|       384 |
+-----------+
1 row in set (0.00 sec)
 
mysql> select avg(sage) from stu;
+-----------+
| avg(sage) |
+-----------+
|   22.5882 |
+-----------+
1 row in set (0.02 sec)
 
mysql>
 
 
```
 
#### 分组
 
我们可以根据某个字段或某些字段对From所拿到的数据进行分组.比如按照性别分组
 
```mysql
mysql> select * from stu group by sgender;
ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregate
d column 'tc39.stu.sid' which is not functionally dependent on columns in GROUP BY clause; this is i
ncompatible with sql_mode=only_full_group_by
mysql>
 
# 上面这个错可以总结为:想要分组.select后面的字段列表要么出现在分组的条件中,要么出现在聚合函数中.
 
```
 
```mysql
mysql> select count(sid),sgender from stu group by sgender;
+------------+---------+
| count(sid) | sgender |
+------------+---------+
|          9 | 男      |
|          8 | 女      |
|          1 |         |
+------------+---------+
3 rows in set (0.00 sec)
 
mysql> select count(sid),sgender from stu group by sgender;
+------------+---------+
| count(sid) | sgender |
+------------+---------+
|         10 | 男      |
|          8 | 女      |
+------------+---------+
2 rows in set (0.00 sec)
 
mysql> select max(sage),sgender from stu group by sgender;
+-----------+---------+
| max(sage) | sgender |
+-----------+---------+
|        35 | 男      |
|        21 | 女      |
+-----------+---------+
2 rows in set (0.00 sec)
 
mysql>
 
```
 
#### HAVING子句
 
对分组后的结果进行筛选.因为在分组后不可以使用where.
 
```mysql
mysql> select max(sage),sgender from stu group by sgender having max(sage) > 30;
+-----------+---------+
| max(sage) | sgender |
+-----------+---------+
|        35 | 男      |
+-----------+---------+
1 row in set (0.00 sec)
 
mysql> select max(sage) as ma,sgender from stu group by sgender having ma > 30;
+------+---------+
| ma   | sgender |
+------+---------+
|   35 | 男      |
+------+---------+
1 row in set (0.00 sec)
 
mysql>
 
```
 
## 子查询
 
子查询就是把一个查询语句嵌套在另外一个查询语句中.内层查询语句的结果可以作为外层查询语句的查询条件或或者是数据源.子查询永远是先执行内层再执行外层.
 
### 带有In的子查询
 
目标:想要查询一些学生的信息.前提是这些必须有考试成绩
 
```mysql
# 普通的查询学生
 
mysql> select * from stu;
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   1 | 张三      |   17 | 男      |
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   4 | 赵六      | NULL | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
18 rows in set (0.00 sec)
 
# 从成绩表中获取所有学生的ID,
mysql> select sid from score;
+------+
| sid  |
+------+
|    1 |
|    2 |
|    3 |
|    3 |
|    3 |
|    5 |
+------+
6 rows in set (0.00 sec)
 
# 利用distinct 关键字来多结果sid进行去重处理.
mysql> select distinct sid from score;
+------+
| sid  |
+------+
|    1 |
|    2 |
|    3 |
|    5 |
+------+
4 rows in set (0.04 sec)
 
# 把上面两条语句整合.把成绩表中的sid作为一个集合作为查询学生表的条件使用.
# 像这样在一个查询语句中嵌入另外一个查询语句.这种写法叫做子查询.
mysql> select * from stu where sid in (select distinct sid from score);
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
|   2 | 李四   |   18 | 男      |
|   3 | 王五   |   19 | 男      |
|   5 | 孙七   |   17 | 女      |
+-----+--------+------+---------+
4 rows in set (0.08 sec)
 
mysql> select * from stu where sid not in (select distinct sid from score);
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   4 | 赵六      | NULL | 男      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
14 rows in set (0.02 sec)
 
mysql> select * from stu where sid not in (select sid from score);
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   4 | 赵六      | NULL | 男      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
14 rows in set (0.00 sec)
 
mysql> select * from stu where sid in (select sid from score);
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
|   2 | 李四   |   18 | 男      |
|   3 | 王五   |   19 | 男      |
|   5 | 孙七   |   17 | 女      |
+-----+--------+------+---------+
4 rows in set (0.00 sec)
 
mysql>
 
```
 
### 带有运算符的子查询
 
对上面的例子做修改.我们从成绩表得到的不再是一个集合而是sid的最大值.求学生表中所有sid大于这个最大值的学生.
 
```mysql
mysql> select * from stu where sid > (select max(sid) from score);
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
13 rows in set (0.04 sec)
 
 
```
 
### 带有Exists关键字的子查询
 
> ​ 必须掌握的.
 
在面试中可能会直接被问到比如子查询in和exists有什么区别.Exists的子查询和其它的子查询有点不一样.
 
使用Exists关键字时,内层查询语句不反悔查询的记录.(无论是单值还是列表).会返回一个真价值.(true或者false).当内层查询语句,查询到满足条件的记录时,返回一个真值(true),否则返回一个假值(false).如果返回为true时,外层查询将进行查询.当返回值为false,外层查询语句不进行查询或者查不到任何记录.
 
```mysql
mysql> select * from stu where exists (select cid from score);
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   1 | 张三      |   17 | 男      |
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   4 | 赵六      | NULL | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
18 rows in set (0.00 sec)
 
mysql> select * from stu where exists (select cid from score where cid = 10);
Empty set (0.00 sec)
 
mysql> select * from stu where sid < 5 and not exists (select cid from score where cid = 10);
+-----+--------+------+---------+
| sid | sname  | sage | sgender |
+-----+--------+------+---------+
|   1 | 张三   |   17 | 男      |
|   2 | 李四   |   18 | 男      |
|   3 | 王五   |   19 | 男      |
|   4 | 赵六   | NULL | 男      |
+-----+--------+------+---------+
4 rows in set (0.00 sec)
 
# 利用内层查询来控制外层查询是否执行
mysql> select * from stu where sid < 5 and exists (select cid from score where cid = 10);
Empty set (0.00 sec)
 
mysql>
 
```
 
### 带有Any的子查询
 
```mysql
mysql> select * from stu where sid > any (select sid from score );
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   4 | 赵六      | NULL | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
17 rows in set (0.00 sec)
 
mysql>
 
 
```
 
Any关键字表示只要满足任何一个条件.就可以执行外层查询.使用Any关键字时,只要满足内层查询语句返回的结果中任何一个记录.就可以通过该条件来执行外层查询.
 
### 带有All的子查询
 
```mysql
mysql> select * from stu where sid > all (select sid from score );
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
13 rows in set (0.00 sec)
 
 
```
 
子查询中得到的结果sid有四个值:1、2、3、5.配合外层循环就构成四个条件
 
- sid > 1
- sid > 2
- sid > 3
- sid > 5
 
向让外层查询语句执行.就必须同时满足上面4个条件.
 
## 联合查询
 
> ​ 也被叫做合并查询
 
联合查询有两个关键字
 
- union
- union all
 
### union
 
使用union和union all的作用都是把两个结果集合并.但是使用union会把重复的去除.而使用union all就是单纯的合并
 
```mysql
mysql> select * from stu
    -> union
    -> select * from stu;
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   1 | 张三      |   17 | 男      |
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   4 | 赵六      | NULL | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
18 rows in set (0.04 sec)
 
mysql> select * from stu
    -> union all
    -> select * from stu;
+-----+-----------+------+---------+
| sid | sname     | sage | sgender |
+-----+-----------+------+---------+
|   1 | 张三      |   17 | 男      |
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   4 | 赵六      | NULL | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
|   1 | 张三      |   17 | 男      |
|   2 | 李四      |   18 | 男      |
|   3 | 王五      |   19 | 男      |
|   4 | 赵六      | NULL | 男      |
|   5 | 孙七      |   17 | 女      |
|   6 | 周八      |   20 | 女      |
|   7 | 吴九      |   21 | 女      |
|   8 | 郑十      |   19 | 女      |
|   9 | 刘一      |   18 | 女      |
|  10 | 陈二      |   20 | 男      |
|  11 | 张国良    |   30 | 男      |
|  12 | 张安峰    |   20 | 女      |
|  13 | 颜习      |   20 | 女      |
|  14 | 李娜      |   21 | 女      |
|  15 | 李安      |   35 | 男      |
|  16 | 王晶      |   29 | 男      |
|  17 | Jack王    |   30 | 男      |
|  18 | 大王      |   30 | 男      |
+-----+-----------+------+---------+
36 rows in set (0.00 sec)
 
mysql>
 
 
```
 
### union all
 
 
 
## 多表查询
 
![img](assets/timg.jpg)
 
### 自连接查询
 
自己连接连接.
 
```mysql
select 字段1,字段2 from 表X as a,表X as b where a.字段 = b.字段
 
```
 
### 内连接查询
 
内连接是最常用的一种连接查询.内连接查询可以查询两个或两个以上的表.内连接的特点是自带连接条件.在使用内连接时,会自动根据两张表中相同含义的字段.一般是父表的主键和子表的外键.作为条件进行查询.
 
比如学会表和成绩表.会自动根据学生表中的学生id和成绩表中的学生id 值相同作为连接条件进行查询.
 
在没有附加条件的情况下得到的结果一般是笛卡尔积.!
 
内连接查询的语法格式
 
```mysql
select 字段列表 from 表1 inner join 表2
 
```
 
```mysql
mysql> select * from stu inner join score;
+-----+--------+------+---------+------+------+------+-------+
| sid | sname  | sage | sgender | scid | sid  | cid  | score |
+-----+--------+------+---------+------+------+------+-------+
|   1 | 张三   |   17 | 男      |    1 |    1 |    1 |    80 |
|   2 | 李四   |   18 | 男      |    1 |    1 |    1 |    80 |
|   3 | 王五   |   19 | 男      |    1 |    1 |    1 |    80 |
|   4 | 赵六   | NULL | 男      |    1 |    1 |    1 |    80 |
|   5 | 孙七   |   17 | 女      |    1 |    1 |    1 |    80 |
|   1 | 张三   |   17 | 男      |    5 |    3 |    3 |   100 |
|   2 | 李四   |   18 | 男      |    5 |    3 |    3 |   100 |
|   3 | 王五   |   19 | 男      |    5 |    3 |    3 |   100 |
|   4 | 赵六   | NULL | 男      |    5 |    3 |    3 |   100 |
|   5 | 孙七   |   17 | 女      |    5 |    3 |    3 |   100 |
|   1 | 张三   |   17 | 男      |    6 |    2 |    2 |    80 |
|   2 | 李四   |   18 | 男      |    6 |    2 |    2 |    80 |
|   3 | 王五   |   19 | 男      |    6 |    2 |    2 |    80 |
|   4 | 赵六   | NULL | 男      |    6 |    2 |    2 |    80 |
|   5 | 孙七   |   17 | 女      |    6 |    2 |    2 |    80 |
|   1 | 张三   |   17 | 男      |    7 |    3 |    3 |    70 |
|   2 | 李四   |   18 | 男      |    7 |    3 |    3 |    70 |
|   3 | 王五   |   19 | 男      |    7 |    3 |    3 |    70 |
|   4 | 赵六   | NULL | 男      |    7 |    3 |    3 |    70 |
|   5 | 孙七   |   17 | 女      |    7 |    3 |    3 |    70 |
|   1 | 张三   |   17 | 男      |    8 |    5 |    4 |    60 |
|   2 | 李四   |   18 | 男      |    8 |    5 |    4 |    60 |
|   3 | 王五   |   19 | 男      |    8 |    5 |    4 |    60 |
|   4 | 赵六   | NULL | 男      |    8 |    5 |    4 |    60 |
|   5 | 孙七   |   17 | 女      |    8 |    5 |    4 |    60 |
|   1 | 张三   |   17 | 男      |    9 |    3 |    4 |    80 |
|   2 | 李四   |   18 | 男      |    9 |    3 |    4 |    80 |
|   3 | 王五   |   19 | 男      |    9 |    3 |    4 |    80 |
|   4 | 赵六   | NULL | 男      |    9 |    3 |    4 |    80 |
|   5 | 孙七   |   17 | 女      |    9 |    3 |    4 |    80 |
+-----+--------+------+---------+------+------+------+-------+
30 rows in set (0.00 sec)
 
mysql>
 
 
```
 
学生表中有5条记录.成绩表中有6条记录.在某有设置条件时按照笛卡尔积5*6一共有30条记录.临时表中的字段.因为` * ` 的原因会是两张表的所有字段整合.
 
使用内连接等价于下面的写法
 
```mysql
mysql> select * from stu,score;
+-----+--------+------+---------+------+------+------+-------+
| sid | sname  | sage | sgender | scid | sid  | cid  | score |
+-----+--------+------+---------+------+------+------+-------+
|   1 | 张三   |   17 | 男      |    1 |    1 |    1 |    80 |
|   2 | 李四   |   18 | 男      |    1 |    1 |    1 |    80 |
|   5 | 孙七   |   17 | 女      |    9 |    3 |    4 |    80 |
+-----+--------+------+---------+------+------+------+-------+
30 rows in set (0.00 sec)
 
 
```
 
内连接可以加条件.但是使用的不是where.而是on
 
```mysql
mysql> select * from stu inner join score on stu.sid = score.sid;
+-----+--------+------+---------+------+------+------+-------+
| sid | sname  | sage | sgender | scid | sid  | cid  | score |
+-----+--------+------+---------+------+------+------+-------+
|   1 | 张三   |   17 | 男      |    1 |    1 |    1 |    80 |
|   3 | 王五   |   19 | 男      |    5 |    3 |    3 |   100 |
|   2 | 李四   |   18 | 男      |    6 |    2 |    2 |    80 |
|   3 | 王五   |   19 | 男      |    7 |    3 |    3 |    70 |
|   5 | 孙七   |   17 | 女      |    8 |    5 |    4 |    60 |
|   3 | 王五   |   19 | 男      |    9 |    3 |    4 |    80 |
+-----+--------+------+---------+------+------+------+-------+
6 rows in set (0.00 sec)
 
 
```
 
```mysql
mysql> select * from stu,score where stu.sid = score.sid;
+-----+--------+------+---------+------+------+------+-------+
| sid | sname  | sage | sgender | scid | sid  | cid  | score |
+-----+--------+------+---------+------+------+------+-------+
|   1 | 张三   |   17 | 男      |    1 |    1 |    1 |    80 |
|   3 | 王五   |   19 | 男      |    5 |    3 |    3 |   100 |
|   2 | 李四   |   18 | 男      |    6 |    2 |    2 |    80 |
|   3 | 王五   |   19 | 男      |    7 |    3 |    3 |    70 |
|   5 | 孙七   |   17 | 女      |    8 |    5 |    4 |    60 |
|   3 | 王五   |   19 | 男      |    9 |    3 |    4 |    80 |
+-----+--------+------+---------+------+------+------+-------+
6 rows in set (0.00 sec)
 
 
```
 
### 外连接查询
 
为什么有内外之分呢?因为内连接的左右两边的表示同级别的
 
```mysql
表1 inner join 表2
 
```
 
这里的表1和表2是同级.没有主次之分.
 
外连接和内连接的区别就在于外连接有主次之分.根据连接的方向来分别主次.什么方向上的连接.对应的表就是主表.
 
主表将会显示全部数据.主表有而次表没有的将会显示null
 
#### 左外连接
 
> ​ 左表为主
 
用学生表左连接成绩表
 
```mysql
mysql> select * from stu left join score on stu.sid = score.sid;
+-----+--------+------+---------+------+------+------+-------+
| sid | sname  | sage | sgender | scid | sid  | cid  | score |
+-----+--------+------+---------+------+------+------+-------+
|   1 | 张三   |   17 | 男      |    1 |    1 |    1 |    80 |
|   2 | 李四   |   18 | 男      |    6 |    2 |    2 |    80 |
|   3 | 王五   |   19 | 男      |    5 |    3 |    3 |   100 |
|   3 | 王五   |   19 | 男      |    7 |    3 |    3 |    70 |
|   3 | 王五   |   19 | 男      |    9 |    3 |    4 |    80 |
|   4 | 赵六   | NULL | 男      | NULL | NULL | NULL |  NULL |
|   5 | 孙七   |   17 | 女      |    8 |    5 |    4 |    60 |
+-----+--------+------+---------+------+------+------+-------+
7 rows in set (0.00 sec)
 
mysql>
 
```
 
学生表中有sid=4的记录.但是成绩表中没有该记录.左连接以左表为主表.所以左表的所有内容都显示.但是主表有次表没有的显示为null
 
#### 右外连接
 
> ​ 右表为主
 
和左连接相反.一般情况下不会使用右连接.因为不是所有的数据库都支持右连接.如果非要用右连接.多数使用左连接来模拟右连接
 
```mysql
select * from 表1 right join 表2 on 表1.字段 = 表2.字段
 
```
 
```mysql
mysql> select * from stu right join score on stu.sid = score.sid;
+------+--------+------+---------+------+------+------+-------+
| sid  | sname  | sage | sgender | scid | sid  | cid  | score |
+------+--------+------+---------+------+------+------+-------+
|    1 | 张三   |   17 | 男      |    1 |    1 |    1 |    80 |
|    3 | 王五   |   19 | 男      |    5 |    3 |    3 |   100 |
|    2 | 李四   |   18 | 男      |    6 |    2 |    2 |    80 |
|    3 | 王五   |   19 | 男      |    7 |    3 |    3 |    70 |
|    5 | 孙七   |   17 | 女      |    8 |    5 |    4 |    60 |
|    3 | 王五   |   19 | 男      |    9 |    3 |    4 |    80 |
+------+--------+------+---------+------+------+------+-------+
6 rows in set (0.00 sec)
 
 
```
 
学生SID=4的记录没有了!
 
使用左连接来模拟下右连接
 
```mysql
select * from 表2 left join 表1 on 表1.字段 = 表2.字段
 
```
 
 
 
# 练习
 
1. [MySQL50练习](<https://www.cnblogs.com/xiao-apple36/p/9613419.html>)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

本文来自投稿,不代表阿习进阶博客立场,如若转载,请注明出处:https://www.yanxias.com/MySQL/19.html

说点什么吧
  • 全部评论(0
    还没有评论,快来抢沙发吧!
点击这里给我发消息