MySQL的连接查询和子查询

263 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

连接查询

在表的连接查询方面有一种现象被称为:笛卡尔积现象。 笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。 怎么避免笛卡尔积现象?当然是加条件进行过滤。 思考:避免了笛卡尔积现象,会减少记录的匹配次数吗? 不会。只不过显示的是有效记录。

内连接之等值连接

查询每个员工的部门名称,要求显示员工名和部门名。

SQL92: select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno and xxx and xxx; //结构不清晰

SQL99:(常用的) select e.ename,d.dname from emp e inner join //inner可以省略,带着inner目的是可读性好一些。 dept d on 连接条件 where ... SQL99语法机构更清晰一些:表的连接条件和后来的where条件分离了。

内连接之非等值连接(连接条件中的关系是非等量关系)

找出每个员工的工资等级,要求显示员工名、工资、工资等级。

select e.ename,e.sal,s.grade from emp e inner join salgrade s on e.sal between s.losal and s.hisal;

自连接(一张表看做两张表,自己连接自己)

找出每个员工的上级领导,要求显示员工名和对应的领导名

员工的领导编号=领导的员工编号 select a.ename,b.ename from emp a inner join emp b on a.mgr=b.empno;

外连接

什么是外连接,和内连接有什么区别? 内连接: 假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。 外连接: 假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表,当附表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。

外连接的分类 左外连接(左连接):表示左边的这张表是主表 右外连接(右连接):表示右边的这张表是主表 左连接有右连接的写法,右连接也会有相应的左连接的写法。

找出每个员工的上级领导、(所有员工都必须查出来)

(错误--内连接) select a.ename '员工' ,b.bname '领导' from emp a (inner)join //inner 可以省略 emp b on a.mgr=b.empno; (正确--外连接) select a.ename '员工',b.ename '领导' from emp a left (outer) join / /out可以省略 emp b on a.mgr=b.empno;

外连接最重要的特点是:主表的数据无条件的全部查询出来

找出哪个部门没有员工

内连接: select e.,d. from emp e right join dept d on e.deptno=d.deptno where e.empno is null;

三张表怎么连接查询

A join B join C on表示:A表和B表先进行表连接,连接之后A表继续和C表进行连接。

找出每一个员工的部门名称以及工资等级。

select e.ename,d.dname,s.grade from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between s.losal and s.hisal;

找出每一个员工的部门名称、工资等级、以及上级领导

select e.ename,d.dname,s.grade from emp e join dept d on e.deptno=d.deptno join salgrade s on e.sal between s.losal and s.hisal left join emp e1 on e.mgr=e1.empno;

子查询

select语句当中嵌套select语句,被嵌套的select语句是子查询。

找出高于平均薪资的员工信息

select *from emp where sal>(select avg(sal) from emp);

找出每个部门平均薪水的薪水等级(from后面嵌套子查询)

第一步:找出每个部门的平均薪水(按照部门编号分组,求sal的平均值) select deptno ,avg(sal) as avgsal from emp group by deptno;

第二步:将以上的查询结果当做临时表t,让t表和salgrade s 表连接,条件是:t.avgral between s.losal and s.histol; 汇总:

select
t.*,s.grade
from
(select deptno ,avg(sal) as avgral from emp group by deptno ) t join
salgrade s on
t.avgral between s.losal and s.hisal;

找出每个员工所在的部门名称,要求显示员工名和部门名

select e.ename,d.dname from emp e join dept d on e.deptno=d.deptno;

select e.ename,e.deptno, (select d.dname from dept d where e.deptno=d.deptno; ) as dname from emp e;

union(可以将查询结果集相加)

找出工作岗位是SALSMAN和MANAGER的员工

第一种:

select ename,job from emp where job='MANAGER' or job='SALSMAN';

第二种:

select ename,job from emp where job in ('MANAGER','SALSMAN');

第三种:UNION

select ename,job from emp where job ='MANAGER' UNION select ename,job from emp where job ='SALSMAN';

两张不相干的表中的数据拼接在一起显示。

select ename from emp union select dname from dept;

注意:查询的列数要相等。

limit(取结果集中的部分数据)

limit是mysql特有的,其他数据库中没有,不通用。(Oracle中有一个相同的机制rownum)

limit startIndex,length

startIndex表示起始位置,从0开始,0表示第一条数据,length表示取几个

取出工资前5名的员工(思路:降序取前5个)

select ename ,sal from emp order by sal desc limit 0,5;

找出工资排名在第四到第九名的员工

select ename ,sal from emp order by sal desc limit 3,6;

分页查询

-- pageNo为当前页,pageSize为每页条数。 limit (pageNo-1)*pageSize,pageSize

本文内容到此结束了,

如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。

如有错误❌疑问💬欢迎各位大佬指出。

主页共饮一杯无的博客汇总👨‍💻

保持热爱,奔赴下一场山海。🏃🏃🏃