-- 创建emp表,并插入数据 CREATE TABLE emp ( id INT AUTO_INCREMENT COMMENT 'ID'PRIMARY KEY, name VARCHAR(50) NOT NULL COMMENT '姓名', age INT COMMENT '年龄', job VARCHAR(20) COMMENT '职位', salary INT COMMENT '薪资', entrydate DATE COMMENT '入职时间', managerid INT COMMENT '直属领导ID', dept_id INT COMMENT '部门ID', FOREIGN KEY (dept_id) REFERENCES dept(id) ) COMMENT '员工表';
-- 查询"销售部"的部门ID SELECT id FROM dept WHERE name ='销售部';
-- 使用子查询查询"销售部"的员工信息 SELECT*FROM emp WHERE dept_id = (SELECT id FROM dept WHERE name ='销售部');
B. 查询在”方东白”入职之后的员工信息
先找出”方东白”的入职日期,然后查询所有在此日期之后入职的员工.
1 2 3 4 5
-- 查询"方东白"的入职日期 SELECT entrydate FROM emp WHERE name ='方东白';
-- 使用子查询查询在"方东白"之后入职的员工 SELECT*FROM emp WHERE entrydate > (SELECT entrydate FROM emp WHERE name ='方东白');
注意事项
子查询在括号内执行,并返回单个值,供外部查询使用.
确保子查询返回的是单个值,否则会导致错误.
子查询可以用在
SELECT
、
FROM
、
WHERE
等子句中.
列子查询
子查询返回的结果是一列(可以是多行),这种子查询称为列子查询. 常用的操作符:IN 、NOT IN 、 ANY 、SOME 、 ALL
A. 查询”销售部”和”市场部”的所有员工信息
要查询两个部门的员工信息,可以先找到这两个部门的ID,然后在员工表中查找.
1 2 3 4 5
-- 查询"销售部"和"市场部"的部门ID SELECT id FROM dept WHERE name ='销售部'OR name ='市场部';
-- 根据部门ID查询员工信息 SELECT*FROM emp WHERE dept_id IN (SELECT id FROM dept WHERE name ='销售部'OR name ='市场部');
B. 查询比财务部所有人工资都高的员工信息
寻找所有财务部员工的工资,然后比较其他员工的工资是否都高于财务部的.
1 2 3 4 5 6 7 8 9
-- 查询财务部的部门ID SELECT id FROM dept WHERE name ='财务部';
-- 查询财务部所有员工的工资 SELECT salary FROM emp WHERE dept_id = (SELECT id FROM dept WHERE name ='财务部');
-- 查询比财务部所有人工资都高的员工信息 SELECT*FROM emp WHERE salary >ALL (SELECT salary FROM emp WHERE dept_id = (SELECT id FROM dept WHERE name ='财务部'));
C. 查询比研发部其中任意一人工资高的员工信息
找出研发部所有人的工资,然后查询工资高于研发部任一员工工资的员工.
1 2 3 4 5 6
-- 查询研发部所有人的工资 SELECT salary FROM emp WHERE dept_id = (SELECT id FROM dept WHERE name ='研发部');
-- 查询比研发部其中任意一人工资高的员工信息 SELECT*FROM emp WHERE salary >ANY (SELECT salary FROM emp WHERE dept_id = (SELECT id FROM dept WHERE name ='研发部'));
注意事项
在使用
IN
子句时,子查询可以返回一个或多个值.
使用
ALL
关键字时,外层查询的结果必须大于子查询返回的所有值.
使用
ANY
(或
SOME
)时,只需外层查询的结果大于子查询返回值中的任意一个即可.
确保子查询与外部查询在逻辑上正确关联,以避免意外的查询结果.
行子查询
子查询返回的结果是一行(可以是多列),这种子查询称为行子查询. 常用的操作符:= 、<> 、IN 、NOT IN
A. 查询与 “张无忌” 的薪资及直属领导相同的员工信息 ;
1 2 3 4 5
-- 这个需求同样可以拆解为两步进行: -- 查询 "张无忌" 的薪资及直属领导 select salary, managerid from emp where name ='张无忌'; -- 查询与 "张无忌" 的薪资及直属领导相同的员工信息 ; select*from emp where (salary,managerid) = (select salary, managerid from emp where name ='张无忌');
表子查询
子查询返回的结果是多行多列,这种子查询称为表子查询. 常用的操作符:IN
A. 查询与 “鹿杖客” , “宋远桥” 的职位和薪资相同的员工信息
1 2 3 4 5
-- 分解为两步执行: -- 查询 "鹿杖客" , "宋远桥" 的职位和薪资 select job, salary from emp where name ='鹿杖客'or name ='宋远桥'; -- 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息 select*from emp where (job,salary) in ( select job, salary from emp where name ='鹿杖客'or name ='宋远桥' );
B. 查询入职日期是 “2006-01-01” 之后的员工信息 , 及其部门信息分解为两步执行:
1 2 3 4 5
-- 入职日期是 "2006-01-01" 之后的员工信息 select*from emp where entrydate >'2006-01-01'; -- 查询这部分员工, 对应的部门信息; select e.*, d.*from (select*from emp where entrydate >'2006-01-01') e left join dept d on e.dept_id = d.id ;
查询员工的姓名、年龄、职位、部门信息(隐式内连接)表: emp,dept 连接条件: emp.dept_id = dept.id```sql select e.name , e.age , e.job , d.name from emp e , dept d where e.dept_id = d.id;
1 2 3
查询年龄小于30岁的员工的姓名、年龄、职位、部门信息(显式内连接) 表: emp,dept 连接条件: emp.dept_id = dept.id```sql select e.name, e.age, e.job, d.name from emp e inner join dept d on e.dept_id = d.id where e.age < 30;
查询拥有员工的部门ID、部门名称表: emp,dept 连接条件: emp.dept_id = dept.id```sql select distinct d.id , d.name from emp e , dept d where e.dept_id = d.id;
1 2 3
查询所有年龄大于40岁的员工, 及其归属的部门名称; 如果员工没有分配部门, 也需要展示出来(外连接) 表: emp,dept 连接条件: emp.dept_id = dept.id```sql select e.*, d.name from emp e left join dept d on e.dept_id = d.id where e.age > 40 ;
查询所有员工的工资等级 表: emp , salgrade 连接条件 : emp.salary >= salgrade.losal and emp.salary <= salgrade.hisal```sql – 方式一 select e.* , s.grade , s.losal, s.hisal from emp e , salgrade s where e.salary >= s.losal and e.salary <= s.hisal; – 方式二 select e.* , s.grade , s.losal, s.hisal from emp e , salgrade s where e.salary between s.losal and s.hisal;
1 2 3 4
查询 "研发部" 所有员工的信息及工资等级表: emp , salgrade , dept 连接条件 : emp.salary between salgrade.losal and salgrade.hisal , emp.dept_id = dept.id 查询条件 : dept.name = '研发部'```sql select e.* , s.grade from emp e , dept d , salgrade s where e.dept_id = d.id and ( e.salary between s.losal and s.hisal ) and d.name = '研发部';
查询 “研发部” 员工的平均工资 表: emp,dept 连接条件: emp.dept_id = dept.id```sql select avg(e.salary) from emp e, dept d where e.dept_id = d.id and d.name = ‘研发部’;
1 2 3 4 5 6
查询工资比 "灭绝" 高的员工信息```sql -- 查询 "灭绝" 的薪资 select salary from emp where name = '灭绝'; -- 查询比她工资高的员工数据 select * from emp where salary > ( select salary from emp where name = '灭绝' );
查询比平均薪资高的员工信息```sql – 查询员工的平均薪资 select avg(salary) from emp; – 查询比平均薪资高的员工信息 select * from emp where salary > ( select avg(salary) from emp );
1 2 3 4 5 6 7 8
查询低于本部门平均工资的员工信息```sql -- 查询指定部门平均薪资 select avg(e1.salary) from emp e1 where e1.dept_id = 1; select avg(e1.salary) from emp e1 where e1.dept_id = 2; -- 查询低于本部门平均工资的员工信息 select * from emp e2 where e2.salary < ( select avg(e1.salary) from emp e1 where e1.dept_id = e2.dept_id );
查询所有的部门信息, 并统计部门的员工人数```sql select d.id, d.name , ( select count(*) from emp e where e.dept_id = d.id ) ‘人数’ from dept d;
1 2 3
```sql select s.name , s.no , c.name from student s , student_course sc , course c where s.id = sc.studentid and sc.courseid = c.id ;