mysql多表查询详解

在mysql中把查询结果去除重复记录【distinct】

如:select distinct job from emp;// 去除员工表工作字段中的重复记录

在这里插入图片描述
需要注意的是distinct只能出现在所有字段的最前方:

如 : 多字段去除重复的记录 
select distinct ename, job ,sal from emp; 

在这里插入图片描述
count() 函数 起到的作用是记数,统计数量

如:select count (distinct job) from emp;select      // 统计工作岗位的数量

在这里插入图片描述

在mysql中的连接查询:

2.1、什么是连接查询?
从一张表中单独查询,称为单表查询。
emp表和dept表联合起来查询数据,从emp表中取员工名字,从dept表中取 部门名字。
这种跨表查询,多张表联合起来查询数据,被称为连接查询。

2.2、连接查询的分类

根据语法的年代分类:
SQL92:1992年的时候出现的语法
SQL99:1999年的时候出现的语法
我们这里重点学习SQL99.(这个过程中简单演示一个SQL92的例子)

根据表连接的方式分类:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接(左连接)
右外连接(右连接)
全连接(不讲)

当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是
两张表条数的乘积,这种现象被称为:笛卡尔积现象。(笛卡尔发现的,这是一个数学现象。)

连接查询如何避免笛卡尔积现象?
连接时加条件,满足这个条件的记录被筛选出来!

select
e.ename,d.dname
from
emp e, dept d
where
e.deptno = d.deptno; // 表起别名。很重要。效率问题。

在这里插入图片描述
在这里插入图片描述
内连接查询之等值连接查询:

查询每个员工所在部门名称,显示员工名和部门名?

sql 92 语法

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

使用SQL99 语法进行查询

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

在这里插入图片描述
//inner可以省略(带着inner可读性更好!!!一眼就能看出来是内连接)
在我们的内连接查询中可以带有inner关键之(带有inner关键字的话效果更好可读性更强)但是inner关键字也可以省略不写。

select 
	e.ename,d.dname
from
	emp e
inner join
	dept d
on
	e.deptno = d.deptno; // 条件是等量关系,所以被称为等值连接。

内连接之非等值连接

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

select 
	e.ename, e.sal, s.grade
from
	emp e
inner join
	salgrade s
on
	e.sal between s.losal and s.hisal; // 条件不是一个等量关系,称为非等值连接。

找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级并且升序排列

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

在这里插入图片描述
内连接查询之(自连接查询)

查询员工的上级领导,要求显示员工名和对应的领导名?
在这里插入图片描述

select e.ename ,e.empno, e.mgr from emp e;

在这里插入图片描述
技巧:一张表看成两张表。

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

在这里插入图片描述
以上就是mysql的内连接查询
主义 :自连接查询将一张表看做是两张表

MYSQL的外连接查询:

内连接:(A和B连接,AB两张表没有主次关系。平等的。)

select 
	e.ename,d.dname
from
	emp e
join
	dept d
on
	e.deptno = d.deptno; //内连接的特点:完成能够匹配上这个条件的数据查询出来。

在mysql中的外连接查询:分为左外连接查询和右外连接查询

select 
	e.ename,d.dname
from
	emp e 
right outer join 
	dept d
on
	e.deptno = d.deptno;**//右外连接查询**

在这里插入图片描述

right代表什么:表示将join关键字右边的这张表看成主表,主要是为了将
这张表的数据全部查询出来,捎带着关联查询左边的表。
在外连接当中,两张表连接,产生了主次关系。

select 
	e.ename,d.dname
from
	dept d 
left outer join 
	emp e
on
	e.deptno = d.deptno;**//左外连接查询**

带有right的是右外连接,又叫做右连接。
带有left的是左外连接,又叫做左连接。
任何一个右连接都有左连接的写法。
任何一个左连接都有右连接的写法。

外连接的查询结果条数一定是 >= 内连接的查询结果条数?
正确。

如:查询每个员工的上级领导,要求显示所有员工的名字和领导名?

select 
	a.ename as '员工名', b.ename as '领导名'
from
	emp a
left join
	emp b
on
	a.mgr = b.empno; 

在这里插入图片描述
三张表,四张表怎么连接?

语法:
		select 
			...
		from
			a
		join
			b
		on
			a和b的连接条件
		join
			c
		on
			a和c的连接条件
		right join
			d
		on
			a和d的连接条件
		
		一条SQL中内连接和外连接可以混合。都可以出现!

如:找出每个员工的部门名称以及工资等级,
要求显示员工名、部门名、薪资、薪资等级?

select 
        e.ename, d.dname, e.sal, s.grade 
from 
        emp e
  join 
        dept d
 on 
        d.deptno = e.deptno // 等值连接
   join
        salgrade s
  on 
       e.sal between s.losal and s.hisal;     // 非等值链接

在这里插入图片描述
如:找出每个员工的部门名称以及工资等级,还有上级领导,
要求显示员工名、领导名、部门名、薪资、薪资等级?

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

在这里插入图片描述
MYSQL子查询:

select语句中嵌套select语句,被嵌套的select语句称为子查询。

子查询都可以出现在哪里呢?
	select
		..(select).
	from
		..(select).
	where
		..(select).

找出比最低工资高的员工姓名和工资?

第一步:查询最低工资是多少

select min(sal) as minsal from emp;

在这里插入图片描述
找出>800的

select ename, sal from emp where sal > 800;

在这里插入图片描述
两条语句合并:

select ename,sal from emp where sal >(select min(sal) as minsal from emp);

在这里插入图片描述
from子句中的子查询

注意:from后面的子查询,可以将子查询的查询结果当做一张临时表。(技巧)

找出每个岗位的平均工资的薪资等级。

第一步:找出每个岗位的平均工资(按照岗位分组求平均值)

select job,avg(sal) from emp group by job; // t表

第二步 :把以上的查询结果就当做一张真实存在的表t

select * from salgrade; // s表

t表和s表进行表连接,条件:t表avg(sal) between s.losal and s.hisal;

select 
			t.*, s.grade // 查询t表中的所有字段,s表中的薪资等级字段
		from
			(select job,avg(sal) as avgsal from emp group by job) t
		join
			salgrade s // 内连接查询
		on
			t.avgsal between s.losal and s.hisal; // 非等值连接

在这里插入图片描述
select后面出现的子查询(这个内容不需要掌握,了解即可!!!)

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

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

在这里插入图片描述
union 关键字 合并查询结果集:

查询工作岗位是MANAGER和SALESMAN的员工?

 select ename '员工名字', job as '工作岗位' from emp where job = 'MANAGER' or job = 'SALESMAN';

在这里插入图片描述
同时还可以使用我们的union语句进行查询

select e.ename as '员工名字' , e.job as '工作岗位' from emp e where job ='MANAGER'
       union
 select e.ename as '员工名字' , e.job as '工作岗位' from emp e where job ='SALESMAN';

在这里插入图片描述
union的效率要高一些。对于表连接来说,每连接一次新表,
则匹配的次数满足笛卡尔积,成倍的翻。。。
但是union可以减少匹配的次数。在减少匹配次数的情况下,
还可以完成两个结果集的拼接。

union在使用的时候的注意事项:

union在进行结果集合并的时候,要求两个结果集的列数相同。
在oracle中由于语法严格 ,不可以,报错。要求:结果集合并时列和列的数据类型也要一致。

limit(非常重要)

完整用法:limit startIndex, length
startIndex是起始下标,length是长度。
起始下标从0开始。
缺省用法:limit 5; 这是取前5.

**按照薪资降序,取出排名在前5名的员工?

select ename, sal from emp order by sal desc limit 0 ,5;
select ename, sal from emp order by sal desc limit 5;// **缺省写法**

在这里插入图片描述

select 
		ename,sal
	from
		emp
	order by 
		sal desc
	limit 5; //取前5
--------------------------------------------------------------
	select 
		ename,sal
	from
		emp
	order by 
		sal desc
	limit 0,5;

注意:mysql当中limit在order by之后执行!!!!!!

取出工资排名在[3-5]名的员工?

 select ename, sal from emp order by sal desc limit 2,3; // 表示的是从第三位开始取,取的位数长度是3

在这里插入图片描述
取出工资排名在[5-9]名的员工?

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

在这里插入图片描述
分页:分页查询

每页显示3条记录
	第1页:limit 0,3		[0 1 2]2页:limit 3,3		[3 4 5]3页:limit 6,3		[6 7 8]4页:limit 9,3		[9 10 11]

每页显示pageSize条记录
第pageNo页:limit (pageNo - 1) * pageSize , pageSize

公式是:记住
	limit (pageNo-1)*pageSize , pageSize
关于DQL语句的大总结:
	select 
		...
	from
		...
	where
		...
	group by
		...
	having
		...
	order by
		...
	limit
		...
	
	执行顺序?
		1.from
		2.where
		3.group by
		4.having
		5.select
		6.order by
		7.limit..

查考自动力节点的b站教程

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值