初识多表查询
前面已经操作过如何在一张表中查询想要的信息,以及提取出相应的字段。可能有时候一张表满足不了我们的查询需求,需要联合两张表甚至多张表一起查询,那么查询语句如果组织的不好很容易出错。并且查询的信息一旦过多很容易出错,那么查询不到想要的信息,对于开发商或者用户来说都是不好的体验。所以多表查询应用极其广泛。
实操
我从网上找了一个非常经典的公司管理系统的数据表,总共有三张表。通过对这三张表的一些信息的查询基本可以掌握以及熟悉对于多表查询的一些操作。这三张表名字叫做 雇员表(emp),部门表(dept),薪水表(salgrade)。
查询雇员名,雇员工资以及雇员所在部门的名字
表名与表名之间用逗号隔开,查询表里的字段用 . 进行标识,
select emp.ename,emp.sal,dept.dname from emp,dept where emp.deptno=dept.deptno;
查询部门号为20的雇员的部门名,员工名以及工资
select ename,sal,dname from emp,dept where emp.deptno=dept.deptno and dept.deptno=20;
查询雇员的名字,薪水以及薪水等级
select ename,sal,grade from emp,salgrade where emp.sal between losal and hisal;
子查询
什么叫自连接查询?就是在一张表上查询多个信息,但是语句是一条语句。
查询一个员工的上级是谁
select ename from emp where empno=(select mgr from emp where ename='BLAKE');
查询一个员工与他同部门的其他员工
select * from emp where deptno=(select deptno from emp where ename='BLAKE');
查询与部门20工作相同的部门的员工的信息但是不包括部门20自己
select * from emp where job in(select distinct job from emp where deptno=20) and deptno<>20;
查询薪水比部门20的所有薪水高的雇员的姓名,薪水和部门号,使用all查询
select ename,sal,deptno from emp where sal>all(select sal from emp where deptno=20);
查询薪水比部门20的任意薪水高的雇员的姓名,薪水和部门号,使用any查询
select ename,sal,deptno from emp where sal>any(select sal from emp where deptno=20);
查询高于自己部门平均工资的员工信息
解释:第一行是将所有的信息从emp中查询出来,第二行是将子查询平均工资作为一个临时表tmp,第三行是条件判断,将所有大于自己部门平均工资的员工过滤出来。
select ename,deptno,sal,asal from emp,
(select avg(sal) asal,deptno dt from emp group by deptno) tmp
where emp.sal > tmp.asal and emp.deptno=tmp.dt;
查询每个部门工资最高的员工信息
select emp.ename,emp.sal,emp.deptno,ms from emp,
(select max(sal) ms,deptno dt from emp group by deptno) tmp
where emp.deptno=tmp.dt and emp.sal=tmp.ms;
查询每个部门的信息(部门名,部门编号,地点)以及有多少人
select dname,dept.deptno,loc,count(*) '部门人数' from emp,dept
where emp.deptno=dept.deptno group by dept.deptno;
快速复制的操作
不得不说这是一个非常nice(sao)的操作,只要一直执行这个操作,表里数据会呈2倍的趋势向上增加。这也叫做自我复制,因为它所有的数据来自它自己本身。
insert into tmp select * from tmp;
去掉重复的记录
当连续查询的时候可能会有重复的数据出现,比如想查询谁在某个部门并且薪水还大于多少,这很有可能就会出现重复的,那么这里就可以使用union关键字进行去重。
select ename,sal ,job from emp where sal>3000 union
select ename,sal,job from emp where job='ANALYST';
内连接
select ename,dname from emp inner join dept on emp.deptno=dept.deptno and ename='BLAKE';
外连接
左外连接:如果联合查询,左侧的表完全显示。
也就是说当我们查询的时候如果条件只满足左边的而右边不存在,那么就只显示左边的数据。这叫做左连接。
语句形式为:
select 字段名 from 表名1 left join 表名2 on 连接条件;
右外连接
与左外连接相反,如果右边的信息存在但左边的信息不存在,那么就只显示右边的。而不是不显示。
语句形式为:
select 字段名 from 表名1 right join 表名2 on 连接条件
比如说要查询部门编号为10的员工的薪水与部门编号。但是可能这个员工是刚入职的薪水还没有发,但是部门已经确定了,这样就可以使用外连接查询。即使没有薪水,也会显示部门编号。