数据库-子查询

概念

子查询是将一个查询语句嵌套在另一个查询语句中。
1、内部嵌套其他select语句的查询,称为外查询或主查询
2、内层查询语句的查询结果,可以为外层查询语句提供查询条件。
3、子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
4、还可以包含比较运算符:= 、 !=、> 、<等

注:
1、子查询要包含在括号内。
2、将子查询放在比较条件的右侧。
3、单行操作符对应单行子查询,多行操作符对应多行子查询。

练习1

CREATE TABLE `emp`  (
  `empno` int(4) NOT NULL,
  `ename` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `job` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `mgr` int(4) NULL DEFAULT NULL,
  `hiredate` date NOT NULL,
  `sai` int(255) NOT NULL,
  `comm` int(255) NULL DEFAULT NULL,
  `deptno` int(2) NOT NULL,
  PRIMARY KEY (`empno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `emp` VALUES (1001, '甘宁', '文员', 1013, '2000-12-17', 8000, NULL, 20);
INSERT INTO `emp` VALUES (1002, '黛绮丝', '销售员', 1006, '2001-02-20', 16000, 3000, 30);
INSERT INTO `emp` VALUES (1003, '殷天正', '销售员', 1006, '2001-02-22', 12500, 5000, 30);
INSERT INTO `emp` VALUES (1004, '刘备', '经理', 1009, '2001-04-02', 29750, NULL, 20);
INSERT INTO `emp` VALUES (1005, '谢逊', '销售员', 1006, '2001-09-28', 12500, 14000, 30);
INSERT INTO `emp` VALUES (1006, '关羽', '经理', 1009, '2001-05-01', 28500, NULL, 30);
INSERT INTO `emp` VALUES (1007, '张飞', '经理', 1009, '2001-09-01', 24500, NULL, 10);
INSERT INTO `emp` VALUES (1008, '诸葛亮', '分析师', 1004, '2007-04-19', 30000, NULL, 20);
INSERT INTO `emp` VALUES (1009, '曾阿牛', '董事长', NULL, '2001-11-17', 50000, NULL, 10);
INSERT INTO `emp` VALUES (1010, '韦一笑', '销售员', 1006, '2001-09-08', 15000, 0, 30);
INSERT INTO `emp` VALUES (1011, '周泰', '文员', 1006, '2007-05-23', 11000, NULL, 20);
INSERT INTO `emp` VALUES (1012, '程普', '文员', 1006, '2001-12-03', 9500, NULL, 30);
INSERT INTO `emp` VALUES (1013, '庞统', '分析师', 1004, '2001-12-03', 30000, NULL, 20);
INSERT INTO `emp` VALUES (1014, '黄盖', '文员', 1007, '2002-01-23', 13000, NULL, 10);
INSERT INTO `emp` VALUES (1015, '张三', '保洁员', 1001, '2013-05-01', 80000, 50000, 50);


CREATE TABLE `dept` (
`deptno`  int NOT NULL ,
`dname`  char(9) NOT NULL ,
`loc`  char(6) NOT NULL 
);

INSERT INTO `dept` VALUES (10, '教研部', '北京');
INSERT INTO `dept` VALUES (20, '学工部', '上海');
INSERT INTO `dept` VALUES (30, '销售部', '广州');
INSERT INTO `dept` VALUES (40, '财务部', '武汉');

1、查询姓名和工资,要求工资=最低工资
mysql> select ename,sai from emp 
    -> where sai=(select min(sai) from emp);
+--------+------+
| ename  | sai  |
+--------+------+
| 甘宁   | 8000 |
+--------+------+


2、查询出高于10号部门的平均工资的员工信息
mysql> SELECT * FROM emp 
    -> WHERE sai>(SELECT AVG(sai) FROM emp 
    -> WHERE deptno=10);
+-------+-----------+-----------+------+------------+-------+-------+--------+
| empno | ename     | job       | mgr  | hiredate   | sai   | comm  | deptno |
+-------+-----------+-----------+------+------------+-------+-------+--------+
|  1004 | 刘备      | 经理      | 1009 | 2001-04-02 | 29750 |  NULL |     20 |
|  1008 | 诸葛亮    | 分析师    | 1004 | 2007-04-19 | 30000 |  NULL |     20 |
|  1009 | 曾阿牛    | 董事长    | NULL | 2001-11-17 | 50000 |  NULL |     10 |
|  1013 | 庞统      | 分析师    | 1004 | 2001-12-03 | 30000 |  NULL |     20 |
|  1015 | 张三      | 保洁员    | 1001 | 2013-05-01 | 80000 | 50000 |     50 |
+-------+-----------+-----------+------+------------+-------+-------+--------

3、查询出比10号部门任何员工薪资高的员工信息
mysql> SELECT * FROM emp 
    -> WHERE sai>(SELECT MAX(sai) FROM emp 
    -> WHERE deptno=10) AND deptno!=10;
+-------+--------+-----------+------+------------+-------+-------+--------+
| empno | ename  | job       | mgr  | hiredate   | sai   | comm  | deptno |
+-------+--------+-----------+------+------------+-------+-------+--------+
|  1015 | 张三   | 保洁员    | 1001 | 2013-05-01 | 80000 | 50000 |     50 |
+-------+--------+-----------+------+------------+-------+-------+--------+

4、查询出比10号部门任意一个员工薪资高的所有员工信息 : 只要比其中随便一个工资都可以
mysql> SELECT * FROM emp WHERE sai >ANY(SELECT sai FROM emp WHERE deptno = 10) AND deptno != 10;
+-------+-----------+-----------+------+------------+-------+-------+--------+
| empno | ename     | job       | mgr  | hiredate   | sai   | comm  | deptno |
+-------+-----------+-----------+------+------------+-------+-------+--------+
|  1002 | 黛绮丝    | 销售员    | 1006 | 2001-02-20 | 16000 |  3000 |     30 |
|  1004 | 刘备      | 经理      | 1009 | 2001-04-02 | 29750 |  NULL |     20 |
|  1006 | 关羽      | 经理      | 1009 | 2001-05-01 | 28500 |  NULL |     30 |
|  1008 | 诸葛亮    | 分析师    | 1004 | 2007-04-19 | 30000 |  NULL |     20 |
|  1010 | 韦一笑    | 销售员    | 1006 | 2001-09-08 | 15000 |     0 |     30 |
|  1013 | 庞统      | 分析师    | 1004 | 2001-12-03 | 30000 |  NULL |     20 |
|  1015 | 张三      | 保洁员    | 1001 | 2013-05-01 | 80000 | 50000 |     50 |
+-------+-----------+-----------+------+------------+-------+-------+--------+

5、获取员工的名字和部门的名字 select后面接子查询
mysql> SELECT ename,(SELECT dname FROM dept d WHERE d.deptno = e.deptno ) 部门名称 FROM emp e;
+-----------+--------------+
| ename     | 部门名称     |
+-----------+--------------+
| 甘宁      | 学工部       |
| 黛绮丝    | 销售部       |
| 殷天正    | 销售部       |
| 刘备      | 学工部       |
| 谢逊      | 销售部       |
| 关羽      | 销售部       |
| 张飞      | 教研部       |
| 诸葛亮    | 学工部       |
| 曾阿牛    | 教研部       |
| 韦一笑    | 销售部       |
| 周泰      | 学工部       |
| 程普      | 销售部       |
| 庞统      | 学工部       |
| 黄盖      | 教研部       |
| 张三      | NULL         |
+-----------+--------------+

6、查询emp表中所有管理层的信息 from后面接子查询
mysql> SELECT * FROM emp e,(SELECT DISTINCT mgr FROM emp) mgrtable WHERE e.empno = mgrtable.mgr;
+-------+-----------+-----------+------+------------+-------+------+--------+------+
| empno | ename     | job       | mgr  | hiredate   | sai   | comm | deptno | mgr  |
+-------+-----------+-----------+------+------------+-------+------+--------+------+
|  1013 | 庞统      | 分析师    | 1004 | 2001-12-03 | 30000 | NULL |     20 | 1013 |
|  1006 | 关羽      | 经理      | 1009 | 2001-05-01 | 28500 | NULL |     30 | 1006 |
|  1009 | 曾阿牛    | 董事长    | NULL | 2001-11-17 | 50000 | NULL |     10 | 1009 |
|  1004 | 刘备      | 经理      | 1009 | 2001-04-02 | 29750 | NULL |     20 | 1004 |
|  1007 | 张飞      | 经理      | 1009 | 2001-09-01 | 24500 | NULL |     10 | 1007 |
|  1001 | 甘宁      | 文员      | 1013 | 2000-12-17 |  8000 | NULL |     20 | 1001 |
+-------+-----------+-----------+------+------------+-------+------+--------+------+

练习2

CREATE TABLE `Authors` (
  `ID` int(11) DEFAULT NULL,
  `Name` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Authors` VALUES (1001,'张三'),(1002,'鸟哥'),(1003,'老男孩'),(1004,'刘江'),(1005,'刘天斯');


CREATE TABLE `Books` (
  `ID` int(11) DEFAULT NULL,
  `Author` int(11) DEFAULT NULL,
  `Title` varchar(100) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `Books` VALUES (101,1001,'MySQL从入门到精通'),(102,1001,'MySQL从入门到放弃'),(103,1002,'鸟哥的私房菜
基础篇'),(104,1002,'鸟哥的私房菜服务器篇'),(105,1003,'shell脚本编程'),(106,1004,'python21天速成'),(107,1004,'python web开发');

1) 请写一句 SQL,列出所有作者姓名和其所写书籍名称。 
mysql> select Name,Title from Authors a left join Books b on a.ID=b.Author;
+-----------+--------------------------------+
| Name      | Title                          |
+-----------+--------------------------------+
| 张三      | MySQL从入门到精通              |
| 张三      | MySQL从入门到放弃              |
| 鸟哥      | 鸟哥的私房菜基础篇             |
| 鸟哥      | 鸟哥的私房菜服务器篇           |
| 老男孩    | shell脚本编程                  |
| 刘江      | python21天速成                 |
| 刘江      | python web开发                 |
| 刘天斯    | NULL                           |
+-----------+--------------------------------+

mysql> select Name,group_concat(Title) from Authors a left join Books b on a.ID=b.Author
    -> group by name;
+-----------+------------------------------------------------------------+
| Name      | group_concat(Title)                                        |
+-----------+------------------------------------------------------------+
| 刘天斯    | NULL                                                       |
| 刘江      | python21天速成,python web开发                              |
| 张三      | MySQL从入门到放弃,MySQL从入门到精通                        |
| 老男孩    | shell脚本编程                                              |
| 鸟哥      | 鸟哥的私房菜基础篇,鸟哥的私房菜服务器篇                    |
+-----------+------------------------------------------------------------+

2) 请写一句 SQL,列出写过两本以上(包括两本)书籍的作者姓名。 
mysql> select name  from Authors where id in(select author from Books group by author having count(1)>=2));
+--------+
| name   |
+--------+
| 张三   |
| 鸟哥   |
| 刘江   |
+--------+

猜你喜欢

转载自blog.csdn.net/m0_46289868/article/details/112768489