MySQL学习02(关联查询/子查询)
关联查询
92语法
两张表或者多张表有相同字段就会有冲突,指定某张表的字段:表名.字段名,但是这样太繁琐,因此在关联查询中,我们要给每个表添加简单的别名
查找2张表:select *from emp e,dept d; //此语句会有问题
这个结果叫做笛卡尔乘积,两张表各自拼接,在开发中要避免
如何避免笛卡尔积?
通过添加条件避免,没有添加必定会出现笛卡尔积 在where中添加两边共同字段的条件,是写死的,如下:
select *from emp e,dept d where e.deptno=d.deptno;
这个属于92语法,没有新关键字,是执行效率比较低的
99语法
也会出现笛卡尔积,99语法中提出了新关键字来提高执行效率
内连接查询
三个关键字:inner join on
inner join 一般一起用(inner可以省略),用来连接两张表,on用来表示条件代替了where
1.等值连接查询 :排除笛卡尔积使用的条件是固定的”=”排除 推荐使用
select * from emp e inner join dept d on e.deptno=d.deptno;
使用on排除笛卡尔积,使用where排除数据
select * from emp e inner join dept d on e.deptno=d.deptno where sal>2000;
2.非等值连接查询:排除笛卡尔积使用的条件不是”=”排除 使用频率不高
例子:查询所有的员工信息,以及对应的工资等级
select e.* ,s.* from emp e inner join salgrade s on e.sal >=s.losal and e.sal<=s.hisal;
select e.* ,s.* from emp e inner join salgrade s on e.sal between s.losal and s.hisal;
3.自连接查询 (基本上没有语法)
表的数量是一张,自己连接自己
查询每个员工的员工编号和员工姓名,以及改员工对应的领导编号和领导姓名
select e.ename \’员工编号\’,e.empno \’员工姓名\’,d.ename \’领导编号\’,d.empno \’领导姓名\’ from emp e inner join emp d on e.mgr=d.empno;
内连接并不能完成所有的情况,当两个表的相同字段的一些值没有匹配时,就会忽略掉这个数据。例如:表1中的员工部门编号为
+——–+———–+———-+ | 名字 | 部门 | 部门编号 | +——–+———–+———-+ | SMITH | CLERK | 20 | | ALLEN | SALESMAN | 30 | | WARD | SALESMAN | 30 | | JONES | MANAGER | 20 | | MARTIN | SALESMAN | 30 | | BLAKE | MANAGER | 30 | | CLARK | MANAGER | 10 | | SCOTT | ANALYST | 20 | | KING | PRESIDENT | 10 | | TURNER | SALESMAN | 30 | | ADAMS | CLERK | 20 | | JAMES | CLERK | 30 | | FORD | null | null | | MILLER | CLERK | 10 | +——–+———–+———-+
表2中员工部门编号为10,20,30,40
+———-+————+ | 部门编号 | 部门名称| +———-+————+ | 10 | ACCOUNTING | | 20 | RESEARCH | | 30 | SALES | | 40 | OPERATIONS | +———-+————+
这时会丢失掉没有部门的员工的数据,这时候需要用到外连接查询
外连接查询
1.左外连接查询(left outer join on)
查询规则:原则上可以查询出左表(主表)的所有数据,以及右表(从表)中的和左表有关的数据
区分左右表: 关键字左边就是左表,右边就是右表
select e.* , d.* from emp left outer join dept d on e.deptno=d.deptno;
2.右外连接查询(right outer join on)
和左外连接完全相反
3.全外连接查询(mysql数据库不支持)
左右外连接的只能显示1张表的所有数据,全外连接能够显示两张表的
左外连接+右外连接+去重复项
关联两个语句:union 并且可以取出重复项
select e.* ,d.* from emp e left outer join dept d on e.deptno=d.deptno
union
select e.* ,d.* from dept d left outer join emp e on e.deptno=d.deptno
最多连接3张表,多了语法允许但是效率不行以及表设计不行
外连接查询关键字顺序
select from (join或者 left join) on where group by heving order by
子查询
子查询会严重影响查询,一定要尽量少用
概念:一条sql语句嵌套另一条sql语句,被嵌套的是子查询
1.子查询可以出现在where之后,结果是作为条件来使用的
例如查询大于平均工资的人:
select * from emp where sal>=(select avg(sal) from emp) order by sal;
2.子查询出现在from之后,是作为临时表来使用的,执行完就会消失
select * from emp e join (select job,avg(sal) avg from emp group by job) t on e.sal>t.avg;
3.子查询出现在select之后,直接作为结果来呈现,禁用!
子查询的结果必须只能用一个结果
limit关键字
limit只能在mysql中使用
显示的结果分批次显示
limit m,n; 参数m:显示的记录要跳过多少条数据开始显示
参数n:要显示多少条数据
select 最后写,执行也是最后
m=0时可以省略 :limit n;
固定公式:
limit (y-1)*13,13; y=页数 显示第4页,(4-1) *13,13;
limit (pageSize-1)*pageNum,pageNum;