隐式内连接: select ... from 左表,右表 where 连接条件; 连接条件一般是 左表.id = 右表.id
【推荐】显示内连接: select ... from 左表 [inner] join 右表 on 连接条件;
这两个效果是一样的:
为什么说 where 是隐式,而 inner join on 是显示呢? 首先,这个单词的意思翻译过来就是内连接,where 并没显示是连接查询,然而有关联条件的约束,也能达到连接查询的效果,所以 where 是隐式内连接。
ii. 示例
-- 内连接-- 隐式内连接SELECT*FROM emp e,dept d WHERE e.dept_id = d.id;-- 显示内连接SELECT*FROM emp e INNERJOIN dept d ON e.dept_id = d.id;-- 查询唐僧的 id,姓名,性别,工资和所在部门名称-- 1.确定查询表SELECT*FROM emp e INNERJOIN dept d;-- 2.确定连接条件SELECT*FROM emp e INNERJOIN dept d ON e.dept_id = d.id;-- 3.确定显示字段SELECT e.id,e.name,e.gender,e.salary,d.name FROM emp e INNERJOIN dept d ON e.dept_id = d.id;-- 4.确定业务条件SELECT e.id,e.name,e.gender,e.salary,d.name FROM emp e INNERJOIN dept d ON e.dept_id = d.id WHERE e.name ='唐僧';
语法:select ...from 左表 right [outer] join 右表 on 连接条件;
ii. 示例
# 左外连接(推荐)-- 查询所有员工信息及对应的部门名称SELECT*FROM emp e LEFTOUTERJOIN dept d ON e.dept_id = d.id;-- 查询所有部门及对应的员工信息SELECT*FROM dept d LEFTJOIN emp e ON e.dept_id = d.id;# 右外连接-- 查询所有部门及对应的员工信息SELECT*FROM emp e RIGHTOUTERJOIN dept d ON e.dept_id = d.id;
连接关系左右互换有影响吗? 有影响。selecet * from A left outer join B on 连接条件。A 表在左边,A 表为左表,A 表数据全部显示;B 表为右表,符合条件才显示。如果调换 A、B 两个表的顺序,那么 B 表则为左表了。
3. 子查询(嵌套)
a. 语法
功能:一条 select 语句执行结果,作为另一条 select 语法的一部分。
子查询语法:
查询结果单值: SELECT MAX(salary) FROM emp;
查询结果单列多值: SELECT salary FROM emp;
查询结果多列多值: SELECT * FROM emp;
语法及规律:
子查询结果为单列,肯定作为条件在 where 后面使用: select ... from 表名 where 字段 in (子查询);
子查询结果为多列,一般作为虚拟表(又称临时表)在 from 后面使用: select ... from (子查询) as 表别名;
b. 示例
# 子查询# 子查询结果为单值-- 1 查询工资最高的员工是谁? SELECT*FROM emp WHERE salary =(SELECTMAX(salary)FROM emp);-- 2 查询工资小于平均工资的员工有哪些?-- 2.1 先求出平均工资SELECTAVG(salary)FROM emp;-- 2.2 查询低于平均工资的员工SELECT*FROM emp WHERE salary <(SELECTAVG(salary)FROM emp);# 子查询结果为单列多行-- 1 查询工资大于5000的员工,来自于哪些部门的名字 -- 1.1 查询工资大于5000的员工SELECT dept_id FROM emp WHERE salary >5000;-- 1.2 来自于哪些部门的名字 SELECT*FROM dept WHERE id IN(SELECT dept_id FROM emp WHERE salary >5000);-- 2 查询开发部与财务部所有的员工信息-- 2.1 根据部门名称,查询部门主键SELECT id FROM dept WHERE`name`IN('开发部','财务部');-- 2.2 根据部门id查询员工信息SELECT*FROM emp WHERE dept_id IN(SELECT id FROM dept WHERE`name`IN('开发部','财务部'));# 子查询结果为多列多行-- 1 查询出`dept`,包括部门名称-- 方案一-- 1.1 查询出2011年以后入职的员工信息SELECT*FROM emp WHERE join_date >'2011-1-1';-- 1.2 通过临时表跟部门表关联SELECT*FROM(SELECT*FROM emp WHERE join_date >'2011-1-1') e LEFTJOIN dept d ON e.dept_id = d.id;-- 方案二-- 1.1 先实现二张表关联SELECT*FROM emp e LEFTOUTERJOIN dept d ON e.dept_id = d.id;-- 1.2 再过滤2011年以后入职的SELECT*FROM emp e LEFTOUTERJOIN dept d ON e.dept_id = d.id WHERE e.join_date >'2011-1-1';
-- 1 查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述-- 1.1 确定几张表?SELECT*FROM emp e INNERJOIN job j;-- 1.2 确定连接条件SELECT*FROM emp e INNERJOIN job j ON e.job_id = j.id;-- 1.3 确定显示字段(列)SELECT e.id,e.ename,e.salary,j.jname,j.description FROM emp e INNERJOIN job j ON e.job_id = j.id;
-- 2 查询所有员工信息。显示员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置-- 2.1 确定几张表?SELECT*FROM emp e
INNERJOIN job j
INNERJOIN dept d;-- 2.2 确定连接条件SELECT*FROM emp e
INNERJOIN job j ON e.job_id = j.id
INNERJOIN dept d ON e.dept_id = d.id;-- 2.3 确定显示字段SELECT e.id,e.ename,e.salary,j.jname,j.description,d.dname,d.loc FROM emp e
INNERJOIN job j ON e.job_id = j.id
INNERJOIN dept d ON e.dept_id = d.id;
-- 3 查询所有员工信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级-- 3.1 确定几张表SELECT*FROM emp e
INNERJOIN job j
INNERJOIN dept d
INNERJOIN salarygrade sg;-- 3.2 确定连接条件SELECT*FROM emp e
INNERJOIN job j ON e.job_id = j.id
INNERJOIN dept d ON e.dept_id = d.id
INNERJOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary;-- 3.3 确定显示字段SELECT e.ename,e.salary,j.jname,j.description,d.dname,d.loc,sg.grade FROM emp e
INNERJOIN job j ON e.job_id = j.id
INNERJOIN dept d ON e.dept_id = d.id
INNERJOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary;
-- 4 查询经理的信息。显示员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级-- 直接将第三题代码粘过来SELECT e.ename,e.salary,j.jname,j.description,d.dname,d.loc,sg.grade FROM emp e
INNERJOIN job j ON e.job_id = j.id
INNERJOIN dept d ON e.dept_id = d.id
INNERJOIN salarygrade sg ON e.salary BETWEEN sg.losalary AND sg.hisalary
WHERE j.jname ='经理';
-- 5 查询出部门编号、部门名称、部门位置、部门人数 (重点)-- 5.1 查询出部门编号、部门名称、部门位置SELECT*FROM dept;-- 5.2 部门人数(员工表:分组+聚合 )SELECT dept_id,COUNT(*)AS total FROM emp GROUPBY dept_id;-- 5.3 部门表左外关联临时表SELECT d.id,d.dname,d.loc,e.total FROM dept d
LEFTJOIN(SELECT dept_id,COUNT(*)AS total FROM emp GROUPBY dept_id) e ON d.id = e.dept_id;
> 关系图
c. 左外链接
-- 6 查询每个员工的名称及其上级领导的名称(自关联)SELECT
yuangong.id,
yuangong.ename,
lingdao.id,
lingdao.ename
FROM
emp yuangong
LEFTOUTERJOIN emp lingdao
ON yuangong.mgr = lingdao.id ;