多表查询
关联查询 - 作用:可以跨多表查询
查询出员工的名字和他所在部门的名字【错误】
select e.empno,e.ename,d.deptno,d.dname
from emp e,dept d
错误原因:
以上写法会出现笛卡尔积,产生很多冗余错误的数据,如果要
排除笛卡尔积,则应该使用where字句进行条件的过滤.
正确写法:传统方式
select e.empno,e.ename,d.deptno,d.dname
from emp e,dept d
where e.deptno = d.deptno
[表的主键 = 表的外键]
给表格取别名,可以简化SQL语句,还可以区别不同的列
正确写法:join方式
select e.firstname,d.name from semp e join sdept on e.deptid=d.id;
多表连接查询
1. 內连接[ inner ] join : 多表连接满足指定条件的结果集
table1 t1 inner join table2 t2
on t1.列 = t2.列
a. 等值连接 : 连接的条件是 = 连接 on t1.列 = t2.列
b.不等值连接 : 连接的条件是 不相等 连接 on t1.列 > t2.列
c.自然连接 natural join (删除重复列)
- 使用表别名可以简化查询
- 使用表名(表别名)前缀可提高查询效率
(第一种写法)
select *
from customer c,recevice_address r
where c.cust_id =r.cust_id
(第二种写法)
select *
from customer c
Inner join myorder m on c.cust_id =m.cust_id
2. 外连接 outer join
a. 左外连接 left [ outer ] join : 把左边不满足条件的记录也需要查询出来
(第一种写法)
select *
from customer c left join recevice_address r
on c.cust_id = r.cust_id
(第二种写法)
select *
from customer c,myorder m
where c.cust_id = m.cust_id
b.右外连接 right [ outer ] join :把右边不满足条件的记录也需要查询出来
(第一种写法)
select *
from customer c right join recevice_address r
on c.cust_id = r.cust_id
(第二种写法)
select *
from customer c ,myorder m
where c.cust_id = m.cust_id
3.完全连接
将A表和B表中的数据完全匹配。(FULL JOIN)在查询资料后发现MySQL上不适配,属于order数据库的方法。
-- 不适配版本
SELECT *
FROM dbo.customer
full join dbo.recevice_address
on dbo.customer.cust_id = dbo.recevice_address.cust_id
联合查询用到的方法是先用左连接查出来后在差右连接。左右两个全部查出来后用UNION来拼接起来。
select *
from customer c
left join recevice_address r on c.cust_id = r.cust_id
union
select *
from customer c
RIGHT JOIN recevice_address r on c.cust_id = r.cust_id
4.自连接: 把表复制一份 作为另一个表
注意: 表一定要取别名
(1). 查询出在 ACCOUNTING 部门的员工编号,姓名
select empno, ename
from emp e join dept d
on e.deptno = d.deptno
where d.dname = 'ACCOUNTING ';
(2) 查询出所有部门的所有员工,列出所有部门信息、员工信息
select *
from emp e join dept d
on e.deptno = d.deptno;
5. 自然连接
select *
from emp natural join dept
(3). 查询在北京工作的员工的平均薪资
select avg(salary)
from emp e join dept d
on e.deptno = d.deptno
where d.loc = 'beijing';
(4).查询出各部门的员工人数(没有员工的部门也需要统计)
select d.deptno , count(e.empno)
from emp e right outer join dept d
on e.deptno = d.deptno
group by d.deptno;
select d.deptno , count(e.empno)
from dept d left outer join emp e
on e.deptno = d.deptno
group by d.deptno;
+--------+----------+
| deptno | count(*) |
+--------+----------+
| 10 | 3 |
| 20 | 5 |
| 30 | 6 |
| 40 | 0 |
| 50 | 0 |
+--------+----------+
(5). 查询出员工编号,姓名,和该员工上级领导的编号与姓名 (给结果列名 取别名)
select e.empno 员工编号, e.ename 员工姓名,e.mgr 上级领导的编号, m.ename 上级领导的名称
from emp e join emp m
on e.mgr = m.empno ;
(6). 查询出员工编号,姓名,和该员工上级领导的编号与姓名 (给结果列名 取别名 , 没有上级领导的记录也需要查询)
select e.empno 员工编号, e.ename 员工姓名,e.mgr 上级领导的编号, m.ename 上级领导的名称
from emp e left join emp m
on e.mgr = m.empno ;
(7). 查询出各年份员工入职人数
select YEAR(emp.hiredate),COUNT(emp.empno)
from emp
GROUP BY YEAR(emp.hiredate);
(8). 查询出各年份各月份员工入职人数
select YEAR(emp.hiredate),MONTH(emp.hiredate),COUNT(emp.empno)
from emp
GROUP BY YEAR(emp.hiredate),MONTH(emp.hiredate);
(9). 查询出在 ACCOUNTING 部门的员工编号,姓名
select e.empno,e.ename
from emp e right join dept d
on e.deptno=d.deptno
where d.dname='ACCOUNTING';
(10). 查询在北京工作的员工的平均薪资
(11). 查询出谌燕老师带的课程的学生有哪些**
select t.tname,c.cname,stu.sname
from teacher t join course c
on t.tno = c.tno
join score s
on c.cno = s.cno
join student stu
on stu.sno = s.sno
where t.tname ='谌燕'
课堂练习
-- 1.查询出员工的信息(包含部门信息)
select e.empno,e.ename,e.job,d.deptno,d.dname,d.loc
from emp e,dept d --笛卡尔积【错误】
-- 多表查询
1、内链接:inner join
(1).等值链接
2、外链接:outer join
select e.empno,e.ename,e.job,d.deptno,d.dname,d.loc
from emp e inner join dept d
on e.deptno = d.deptno
-- 2.查询出姓名'JONES'员工的编号,薪资,所在部门编号,部门名称这些信息
select e.empno,e.ename,e.job,d.deptno,d.dname,d.loc
from emp e inner join dept d
on e.deptno = d.deptno
where ename = 'JONES'
-- 3. 查询各部门的员工人数,显示部门编号,部门名称,员工人数
select e.deptno,d.dname,count(e.ename)
from emp e inner join dept d
on e.deptno = d.deptno
group by e.deptno
-- 4. 查询在'SALES'部门的员工平均薪资
select d.dname,avg(e.salary)
from emp e inner join dept d
on e.deptno =d.deptno
where d.dname ='SALES'
-- 5. 查询出员工的编号,姓名,薪资,与他的领导的编号,姓名,薪资
select e.empno,e.ename,e.salary,e.mgr,m.ename,m.salary
from emp e join emp m
on e.mgr = m.empno
-- 6. 查询在北京工作的员工的平均薪资
select d.loc,avg(e.salary)
from emp e inner join dept d
on e.deptno = d.deptno
where d.loc = 'beijing'
-- 7.查询各部门的人数,显示部门编号,部门名称,人数
select e.deptno,d.dname,count(e.ename)
from emp e join dept d
on e.deptno = d.deptno
group by e.deptno
-- 外链接
查询出员工编号,姓名,和该员工上级领导的编号与姓名(给结果列名 取别名,没有上级领导的也需要查询)
select e.empno,e.ename,e.salary,e.mgr,m.ename,m.salary
from emp e left outer join emp m
on e.mgr = m.empno
-- left outer join 交集部分,左外链接
select e.empno,e.ename,e.salary,e.mgr,m.ename,m.salary
from emp e right outer join emp m
on e.mgr = m.empno
-- right outer join 交集部分,右外链接
-- 统计各部门的人数,没有员工的部门,也要查询出来
select d.deptno ,count(empno)
from emp e right join dept d
on e.deptno = d.deptno
group by d.deptno