特殊形式的查询

子查询

指把一个查询语句嵌套在另一个查询语句中

SELECT 字段名称,... FROM tbl_name1 WHERE col_name1=(SELECT col_name2 FROM tbl_name2)

我们可以看到有两层查询结果,内层查询语句的结果可以作为外层查询语句的条件。

由[NOT] IN引发的子查询

SELECT 字段名称,... FROM tbl_name WHERE col_name [NOT] IN (条件)

由比较运算符引出的子查询

SELECT 字段名称,... FROM tbl_name WHERE col_name 比较运算符(条件)

由EXISTS引发的子查询

如果内层查询查到了结果存在,那么返回的是真值,也就执行外层查询;不然的话返回的是假值,不执行外层查询。

SELECT 字段名称,... FROM tbl_name WHERE col_name EXISTS(内层查询)

由ANY SOME ALL引发的子查询

在这里插入图片描述

我们来稍微解释几个。

>=ANY表示大于等于内层查询的最小值。也就是大于等于内层查询的任意一个。

>=SOME表示大于等于最小值。也就是大于等于内层查询的有一些。

>=ALL代表大于等于内层查询的最大值。也就是大于等于内层查询的每一个

SELECT 字段名称,... FROM tbl_name WHERE col_name 关系运算符 ANY|SOME|ALL(内层查询);

由子查询带来的一些语句

INSERT … SELECT

将查询出来的结果写入到表中。包括INSERT … SETUPDATE … SET 的形式都可以使用到我们的子查询。实现数据的导入。

CREATE … SELECT

在创建表时将另外一个表中的数据写入到表中。实现数据的导入。

CREATE TABLE tbl_name(
	...
)SELECT 字段名称,... FROM emp;
-- 创建表结构一样的表
CREATE TABLE tbl_name1 LIKE tbl_name2;

测试

测试子查询

测试由IN引发的子查询

下面是测试用表的内容

SELECT * FROM emp;
+----+----------+-----+------+------+-------+
| id | username | age | sex  | addr | depId |
+----+----------+-----+------+------+-------+
|  1 | king     |  25 | 保密 | 北京 |     1 |
|  2 | queen    |  26 | 保密 | 北京 |     2 |
|  3 | imooc    |  27 | 保密 | 北京 |     1 |
|  4 | lily     |  28 | 保密 | 北京 |     1 |
|  5 | rose     |  29 | 保密 | 北京 |     3 |
|  6 | john     |  30 | 保密 | 北京 |     3 |
|  7 | 测试用户 |  39 | 保密 | 北京 |     6 |
+----+----------+-----+------+------+-------+

SELECT * FROM dep;
+----+---------------+-----------------+
| id | depName       | depDesc         |
+----+---------------+-----------------+
|  1 | PHP教学部     | 研发PHP课件     |
|  2 | JAVA教学部    | 研发JAVA课件    |
|  3 | WEB前端教学部 | 研发WEB前端课件 |
|  4 | IOS教学部     | 研发IOS课件     |
+----+---------------+-----------------+

查询出emp表中的depId在dep表中有对应的记录

SELECT * FROM emp WHERE depID IN(1,2,3,4);
+----+----------+-----+------+------+-------+
| id | username | age | sex  | addr | depId |
+----+----------+-----+------+------+-------+
|  1 | king     |  25 | 保密 | 北京 |     1 |
|  2 | queen    |  26 | 保密 | 北京 |     2 |
|  3 | imooc    |  27 | 保密 | 北京 |     1 |
|  4 | lily     |  28 | 保密 | 北京 |     1 |
|  5 | rose     |  29 | 保密 | 北京 |     3 |
|  6 | john     |  30 | 保密 | 北京 |     3 |
+----+----------+-----+------+------+-------+

我们可以发现在上面IN的括号中就是dep表中id的值,我们可以替换一下里面已有的内容,改成查询语句

SELECT * FROM emp WHERE depId IN(SELECT id FROM dep);
+----+----------+-----+------+------+-------+
| id | username | age | sex  | addr | depId |
+----+----------+-----+------+------+-------+
|  1 | king     |  25 | 保密 | 北京 |     1 |
|  2 | queen    |  26 | 保密 | 北京 |     2 |
|  3 | imooc    |  27 | 保密 | 北京 |     1 |
|  4 | lily     |  28 | 保密 | 北京 |     1 |
|  5 | rose     |  29 | 保密 | 北京 |     3 |
|  6 | john     |  30 | 保密 | 北京 |     3 |
+----+----------+-----+------+------+-------+

还可以使用NOT IN

SELECT * FROM emp WHERE depId NOT IN(SELECT id FROM dep);
+----+----------+-----+------+------+-------+
| id | username | age | sex  | addr | depId |
+----+----------+-----+------+------+-------+
|  7 | 测试用户 |  39 | 保密 | 北京 |     6 |
+----+----------+-----+------+------+-------+
测试由比较运算符引出的子查询
-- 创建学院表
CREATE TABLE IF NOT EXISTS stu(
	id TINYINT UNSIGNED AUTO_INCREMENT KEY COMMENT '编号',
    username VARCHAR(20) NOT NULL UNIQUE COMMENT '学院名称',
    score TINYINT UNSIGNED NOT NULL COMMENT '学院考试分数'
);
INSERT stu(username,score) VALUES('king',95),
('queen',75),
('zhangsan',69),
('lisi',78),
('wangwu',87),
('zhaoliu',88),
('tianqi',98),
('ceshi',99),
('tiancai',50);

-- 创建分数基本表
CREATE TABLE IF NOT EXISTS level(
	id TINYINT UNSIGNED KEY AUTO_INCREMENT COMMENT '编号',
    score TINYINT UNSIGNED COMMENT '分数'
);
INSERT level(score) VALUES(90),
(80),
(70);
-- 查询出成绩优秀的学员
SELECT id,username,score FROM stu
WHERE score>=(SELECT score FROM level WHERE id=1);
+----+----------+-------+
| id | username | score |
+----+----------+-------+
|  1 | king     |    95 |
|  7 | tianqi   |    98 |
|  8 | ceshi    |    99 |
+----+----------+-------+
-- 查询出没有得到评级的学员
SELECT id,username,score FROM stu
WHERE score<=(SELECT score FROM level WHERE id=3);
+----+----------+-------+
| id | username | score |
+----+----------+-------+
|  3 | zhangsan |    69 |
|  9 | tiancai  |    50 |
+----+----------+-------+
测试由EXISTS引发的子查询

下面是测试表的内容

SELECT * FROM emp;
+----+----------+-----+------+------+-------+
| id | username | age | sex  | addr | depId |
+----+----------+-----+------+------+-------+
|  1 | king     |  25 | 保密 | 北京 |     1 |
|  2 | queen    |  26 | 保密 | 北京 |     2 |
|  3 | imooc    |  27 | 保密 | 北京 |     1 |
|  4 | lily     |  28 | 保密 | 北京 |     1 |
|  5 | rose     |  29 | 保密 | 北京 |     3 |
|  6 | john     |  30 | 保密 | 北京 |     3 |
|  7 | 测试用户 |  39 | 保密 | 北京 |     6 |
+----+----------+-----+------+------+-------+

SELECT * FROM dep;
+----+---------------+-----------------+
| id | depName       | depDesc         |
+----+---------------+-----------------+
|  1 | PHP教学部     | 研发PHP课件     |
|  2 | JAVA教学部    | 研发JAVA课件    |
|  3 | WEB前端教学部 | 研发WEB前端课件 |
|  4 | IOS教学部     | 研发IOS课件     |
+----+---------------+-----------------+

对于下面语句的内查询,显然是不存在的。

SELECT * FROM emp WHERE EXISTS(SELECT depName FROM dep WHERE id=10);
Empty set

对于下面语句的内查询,显然是存在的,外查询也就执行了。

SELECT * FROM emp WHERE EXISTS(SELECT depName FROM dep WHERE id=1);
+----+----------+-----+------+------+-------+
| id | username | age | sex  | addr | depId |
+----+----------+-----+------+------+-------+
|  1 | king     |  25 | 保密 | 北京 |     1 |
|  2 | queen    |  26 | 保密 | 北京 |     2 |
|  3 | imooc    |  27 | 保密 | 北京 |     1 |
|  4 | lily     |  28 | 保密 | 北京 |     1 |
|  5 | rose     |  29 | 保密 | 北京 |     3 |
|  6 | john     |  30 | 保密 | 北京 |     3 |
|  7 | 测试用户 |  39 | 保密 | 北京 |     6 |
+----+----------+-----+------+------+-------+
测试由ANY|SOME|ALL引发的子查询

下面是测试表的内容

SELECT * FROM stu;
+----+----------+-------+
| id | username | score |
+----+----------+-------+
|  1 | king     |    95 |
|  2 | queen    |    75 |
|  3 | zhangsan |    69 |
|  4 | lisi     |    78 |
|  5 | wangwu   |    87 |
|  6 | zhaoliu  |    88 |
|  7 | tianqi   |    98 |
|  8 | ceshi    |    99 |
|  9 | tiancai  |    50 |
+----+----------+-------+

SELECT * FROM level;
+----+-------+
| id | score |
+----+-------+
|  1 |    90 |
|  2 |    80 |
|  3 |    70 |
+----+-------+
ANY
SELECT * FROM stu
WHERE score>=ANY(SELECT score FROM LEVEL);
+----+----------+-------+
| id | username | score |
+----+----------+-------+
|  1 | king     |    95 |
|  2 | queen    |    75 |
|  4 | lisi     |    78 |
|  5 | wangwu   |    87 |
|  6 | zhaoliu  |    88 |
|  7 | tianqi   |    98 |
|  8 | ceshi    |    99 |
+----+----------+-------+
SELECT * FROM stu
WHERE score=ANY(SELECT score FROM level);
Empty set
SOME
SELECT * FROM stu
WHERE score>=SOME(SELECT score FROM LEVEL);
+----+----------+-------+
| id | username | score |
+----+----------+-------+
|  1 | king     |    95 |
|  2 | queen    |    75 |
|  4 | lisi     |    78 |
|  5 | wangwu   |    87 |
|  6 | zhaoliu  |    88 |
|  7 | tianqi   |    98 |
|  8 | ceshi    |    99 |
+----+----------+-------+
ALL
SELECT * FROM stu
WHERE score>=ALL(SELECT score FROM LEVEL);
+----+----------+-------+
| id | username | score |
+----+----------+-------+
|  1 | king     |    95 |
|  7 | tianqi   |    98 |
|  8 | ceshi    |    99 |
+----+----------+-------+
SELECT * FROM stu
WHERE score<ALL(SELECT score FROM level);
+----+----------+-------+
| id | username | score |
+----+----------+-------+
|  3 | zhangsan |    69 |
|  9 | tiancai  |    50 |
+----+----------+-------+
SELECT * FROM stu
WHERE score!=ALL(SELECT score FROM level);
+----+----------+-------+
| id | username | score |
+----+----------+-------+
|  1 | king     |    95 |
|  2 | queen    |    75 |
|  3 | zhangsan |    69 |
|  4 | lisi     |    78 |
|  5 | wangwu   |    87 |
|  6 | zhaoliu  |    88 |
|  7 | tianqi   |    98 |
|  8 | ceshi    |    99 |
|  9 | tiancai  |    50 |
+----+----------+-------+

测试CREATE … INSERT 和 INSERT … SELECT

-- 创建一个user4表,将emp表中的id username字段插入到新建的user4表中
CREATE TABLE user4(
	id INT UNSIGNED AUTO_INCREMENT KEY,
    username VARCHAR(20)
)SELECT id,username FROM emp;
mysql> SELECT * FROM user4;
+----+----------+
| id | username |
+----+----------+
|  1 | king     |
|  2 | queen    |
|  3 | imooc    |
|  4 | lily     |
|  5 | rose     |
|  6 | john     |
|  7 | 测试用户 |
+----+----------+
-- 将user3表中的用户名表写入到user4表中
INSERT user4(username) SELECT username FROM user3;
SELECT * FROM user3;
+----+----------+------------+-------+
| id | username | email      | proId |
+----+----------+------------+-------+
|  1 | a        | 123@qq.com |     1 |
|  2 | b        | 123@qq.com |     1 |
|  3 | c        | 123@qq.com |     1 |
|  4 | d        | 123@qq.com |     2 |
|  5 | e        | 123@qq.com |     3 |
|  6 | f        | 123@qq.com |     1 |
|  7 | g        | 123@qq.com |     1 |
+----+----------+------------+-------+
SELECT * FROM user4;
+----+----------+
| id | username |
+----+----------+
|  1 | king     |
|  2 | queen    |
|  3 | imooc    |
|  4 | lily     |
|  5 | rose     |
|  6 | john     |
|  7 | 测试用户 |
|  8 | a        |
|  9 | b        |
| 10 | c        |
| 11 | d        |
| 12 | e        |
| 13 | f        |
| 14 | g        |
+----+----------+
由这两条语句实现数据的导入
-- 创建表结构与user4一样的表user5
-- 注意刚创建完的表是一个空表
CREATE TABLE user5 LIKE user4;

-- 将user4中的数据导入user5
INSERT user5 SELECT id,username FROM user4;
SELECT * FROM user5;
+----+----------+
| id | username |
+----+----------+
|  1 | king     |
|  2 | queen    |
|  3 | imooc    |
|  4 | lily     |
|  5 | rose     |
|  6 | john     |
|  7 | 测试用户 |
|  8 | a        |
|  9 | b        |
| 10 | c        |
| 11 | d        |
| 12 | e        |
| 13 | f        |
| 14 | g        |
+----+----------+

接下来用 INSERT … SET 加上子查询 来实现一下导入数据

INSERT user5 SET username=(SELECT username FROM stu WHERE id=9);
SELECT * FROM user5;
+----+----------+
| id | username |
+----+----------+
|  1 | king     |
|  2 | queen    |
|  3 | imooc    |
|  4 | lily     |
|  5 | rose     |
|  6 | john     |
|  7 | 测试用户 |
|  8 | a        |
|  9 | b        |
| 10 | c        |
| 11 | d        |
| 12 | e        |
| 13 | f        |
| 14 | g        |
| 15 | tiancai  |
+----+----------+

并且因为user5的username字段并不是唯一的,所以我们可以插入重复的值,我们再次执行上面那条插入语句,来介绍一下另一个东东

| 15 | tiancai  |
| 16 | tiancai  |
+----+----------+
-- 去除重复的记录
SELECT DISTINCT(username) FROM user5;
+----------+
| username |
+----------+
| king     |
| queen    |
| imooc    |
| lily     |
| rose     |
| john     |
| 测试用户 |
| a        |
| b        |
| c        |
| d        |
| e        |
| f        |
| g        |
| tiancai  |
+----------+

但是实际上它并没有真的去除掉重复值,只是在这一次查询中去除掉了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值