目录

解决多表查询的关键就是过滤出要显示的列 where语句进行过滤
举例
-- 显示雇员名,雇员工资和所在部门的名字
- -- 当需要指定显示某个表的列是,需要 表.列名
- SELECT ename,sal,dname,dept.deptno
- FROM emp, dept
- WHERE emp.deptno = dept.deptno
-- 显示部门号为10的部门名,员工名,和工资
- SELECT dname,ename,sal,dept.deptno
- FROM dept,emp
- where emp.deptno = dept.deptno and dept.deptno = 10
-- 显示各个员工的姓名,工资和工资的级别
- SELECT ename,sal,grade
- FROM emp,salgrade
- WHERE sal BETWEEN losal AND hisal
自连接是指在同一张表的连接查询【将一张表看做两张表】
思考:显示公司员工和他的上级名字

-- 自连接 要给表取别名
-- 显示员工名字和他的上级 把emp表当两个表使用()
- SELECT worker.ename 职员名,boss.ename boss名
- FROM emp worker,emp boss
- WHERE worker.mgr = boss.empno


-- 如何显示与smith同一个部门的所有员工
-- 1.先得到与smith的部门
-
- SELECT deptno
- FROM emp
- WHERE ename = 'SMITH'
-- 2.把上面的sql语句当作一个子查询来使用
- SELECT * FROM emp
- WHERE deptno = (SELECT deptno
- FROM emp
- WHERE ename = 'SMITH')
-- 如何查询和部门10的工作相同的雇员的 名字,岗位,工资,部门号,但不包括10自己的
- SELECT ename,job,sal,deptno
- FROM emp
- WHERE job in (SELECT job FROM emp
- WHERE deptno = 10) AND deptno != 10

- -- 子查询临时表
- -- 查询emp表中各个部门工资最高的员工
- -- 1.先求出各个部门的最高工资,把他当成一张临时表 max_sal
- SELECT deptno,MAX(sal) max FROM emp
- GROUP BY deptno
- -- 员工信息
- SELECT ename,job,sal,emp.deptno
- FROM(SELECT deptno,MAX(sal) max FROM emp
- GROUP BY deptno) max_sal,emp
- where max_sal.deptno = emp.deptno AND max_sal.max = emp.sal
- -- all和any
- -- 显示工资比部门30所有员工工资都要高的员工信息
- -- 1.部门30工资最高的人
- SELECT MAX(sal) FROM emp WHERE deptno = 30
- -- 方法1,子查询
- SELECT ename,job,sal,deptno FROM emp
- WHERE sal > (SELECT MAX(sal) FROM emp WHERE deptno = 30)
- -- 方法2 all
- SELECT ename,job,sal,deptno FROM emp
- where sal>ALL(SELECT sal from emp WHERE deptno = 30)
- -- 显示工资比部门30的其中一个员工工资高的人
- -- any方法,或者用用工资>30部门工资最低的那个员工
- SELECT ename,job,sal,deptno FROM emp
- WHERE sal >ANY(SELECT sal FROM emp WHERE deptno = 30)

-- 得到与smith的部门和岗位完全相同的所有雇员信息,包括smith自己
- -- 多列子查询
- -- 1.得到smith的部门和岗位
- SELECT deptno ,job FROM emp
- WHERE ename = 'SMITH'
- -- 2.把上面的语句单子查询语句并使用多列查询
- SELECT * FROM emp
- WHERE (deptno,job) = (SELECT deptno ,job FROM emp
- WHERE ename = 'SMITH')

演示如何自我复制表
- -- 1.先创建一个空表
- CREATE TABLE mytable(
- id INT,
- `name` VARCHAR(20),
- `sal` INT,
- `job` VARCHAR(10),
- deptno int)
- -- 将emp表的数据复制过来 使用insert语句
- INSERT INTO mytable
- (id,`name`,sal,job,deptno)
- SELECT empno,ename,sal,job,deptno FROM emp
- -- 查询mytable
- SELECT * FROM mytable
演示如何删除表中的重复数据
- -- 删除mytable表中的重复记录
- -- 1.先创建一个临时表 tmp该表的结构和mytable一样
- CREATE TABLE tmp LIKE mytable
- -- 2.mytable 的记录,通过distinct关键字 处理后 ,把记录复制到tmp
- INSERT INTO tmp
- SELECT DISTINCT * FROM mytable
- -- 3.清楚mytable表中的数据
- DELETE FROM mytable
- -- 4.把临时表的数据复制到mytable中,并删除临时表
- INSERT INTO mytable
- SELECT * FROM tmp;
- DROP TABLE tmp

SELECT ename,sal,job FROM emp WHERE sal>2500 -- 5

SELECT ename,sal,job FROM emp WHERE job = 'MANAGER' -- 3

如果要将两个查询结果合并起来 可以通过union all或者union
union all 不会去重

union会去重


-- 列出部门名称和这些部门的员工名称和工资,同时要求显示出那些没有员工的部门
用之前多表查询的sql 通过两表的deptno进行连接效果如下

因为编号为40的部门没有与员工,所有没显示,这不能解决问题,故应使用表外连接

练习

- -- 左外连接
- SELECT dname ,ename,job
- FROM dept LEFT JOIN emp
- ON dept.deptno = emp.deptno;
- -- 右外连接
- SELECT dname ,ename,job
- FROM emp RIGHT JOIN dept
- ON dept.deptno = emp.deptno;

本质上左右连接都是一样的,要确认是哪张表没有的需要显示,然后根据位置在左还是在右选择左右连接