【mysql】查询语句select之连接查询,子查询

连接方式的分类

连接查询的分类
根据语法的年代分类:

  • SQL92: 1992年 的时候出现的语法
  • SQL99: 1999年 的时候出现的语法

根据表连接的方式分类:

  • 内连接
  • 等值连接
  • 非等值连接
  • 自连接
  • 外连接:
    左外连接(左连接)
    右外连接(右连接)
    全连接

笛卡尔积现象

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

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

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

表起别名

//表起别名。很重要。效率问题。

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

注意:通过笛卡尔积现象得出,表的连接次数越多效率越低,尽量避免表的
连接次数。

内连接

内连接之等值连接。(条件为等值关系)

案例:查询每个员工所在部门名称,显示员工名和部门名?
emp e和dept d表进行连接。条件是: e.deptno = d. deptno
SQL92语法:

select .
 e. ename ,d. dname
from
emp e, dept d
where
e.deptno = d. deptno;
//sql92的缺点:结构不清晰,表的连接条件,和后期进一步 筛选的条件,都放到了where后面.

SQL99语法:

select
e . ename , d. dname
from
emp e
join
dept d
on
e.deptno = d. deptno;
//sql99优点:表连接的条件是独立的,连接之后,如果还需要进一步 筛选,再往后继续添加where;

SQL99语法:

Select
...
from 
...
join
...
on
a和b的连接条件
where
筛选条件

内连接之不等值连接。(条件不为等值关系)

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

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

内连接之自连接

案例:查询员工的上级领导,要求显示员工名和对应的领导名?

select empno , ename , mgr from emp ;

select a.ename,b.ename from emp a join emp b on a.mgr =b.empno;
//将一张表看成两张表

外连接

右外连接

select
e . ename,d. dname
from
emp e
right join 
dept d
on
e. deptno = d. deptno;
//这段代码的意思,将d表的dname字段数据全部查询出来,顺带将e表的ename字段查询出来,如果没有对应的
就为空

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

左外连接

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

带有right的是右外连接,又叫做右连接.
带有left的是左外连接,又叫做左连接.
任何一个右连接都有左连接的写法。
任何一个左连接都有右连接的写法。
思考:外连接的查询结果条数一定是>=内连接的查询结果条数?
正确。

三张表,四张表怎么连接?
语法:

select
from
a
join	
b
on
a和b的连接条件
join
c
on
a和c的连接条件
right join
d
on
a和d的连接条件

一条SQL中内连接和外连接可以混合。都可以出现!

子查询

什么是子查询?

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

子查询都可以出现在哪里呢?

select
. . (select) .
from
(select) .
where
(select) .

Where 后面出现的子查询

案例 查询比最低工资高的员工和工资
实现思路:

	第一步:查询最低工资是多少
	select min(sal) from emp;
	第二步:找出>800的
	select ename,sal from emp where sal > 800;
	第三步:合并
	select ename,sal from emp where sal > (select min(sal) from emp) ;

from子句中的子查询

注意:from后面的子查询,可以将子查询的查询结果当做一张临时表。(技巧)
案例:找出每个岗位的平均工资的薪资等级.

	第一步:找出每个岗位的平均工资(按照岗位分组求平均值)
	select job,avg(sal) from emp group by job; t表
	第二步:把以上的查询结果就当做一张真实存在的表t.
	select *from salgrade; s表
	t表和s表进行表连接
	select
	t.*,s.grade
	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;


select
e . ename , e . deptno, (select dname from dept) as dname
from .
emp e;
	//错误: ERROR 1242 (21000) : Subquery returns more than 1 row

注意:对于select后面的子查询来说,这个子查询只能一次返回1条结果.多于1条,就报错了

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值