连接查询的分类
根据语法的年代分类:
根据表连接的方式分类:
当两张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是
两张表条数的乘积,这种现象被称为:笛卡尔积现象。 (笛卡尔发现的,这是
一个数学现象。)
怎么避免笛卡尔积现象?
连接时加条件,满足这个条件的记录被筛选出来!
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) .
案例 查询比最低工资高的员工和工资
实现思路:
第一步:查询最低工资是多少
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后面的子查询,可以将子查询的查询结果当做一张临时表。(技巧)
案例:找出每个岗位的平均工资的薪资等级.
第一步:找出每个岗位的平均工资(按照岗位分组求平均值)
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
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条,就报错了