(四)sql多表连接查询joinon的⽤法
(四)sql多表连接查询join on的⽤法总结
需要⽤到的表信息如下:
EMP职员表:
dept部门信息表和salgrade薪资等级表:
1. 多表连接
没有任何条件限制,即笛卡⼉积,产⽣的记录数⽬为各表记录的乘积。
select * from table1,table2,table3…
select * from emp,dept
2. 等价连接
在所得的笛卡⼉积中,筛选出有效的信息。在n张表之间,⾄少(n-1)个⼀个连接条件。例⼦如下:
select * from table1,table2 where table1.a=table2.a
SELECT * FROM emp as e ,deptl as d
WHERE e.DEPTNO=d.DEPTNO
3. 不等价连接
当某个值在某⼀范围中,需要求出此范围的级别时,可以应⽤不等价连接。
⽐如:显⽰员⼯姓名,⼯资,⼯资级别
SELECT e.ENAME,e.SAL,g.GRADE FROM emp e,salgrade g
WHERE e.SAL
BETWEEN g.LOW_SAL AND g.HIGH_SAL
注意:如果⼀步写不出来,可以分解开来。
⾸先,求出笛卡尔积,再从笛卡⼉积中筛选条件添加到语句中。
4. ⾃然连接
⾃动的寻2表中的(所有)同名且属性相同的列作为连接条件。使⽤natural join⼦句来完成。
例如:A表中有列a,b,c,d B表中有a,b,x,z
⾃然连接会将A.a=B.a and A.b=B.b 作为连接条件
select * from A natural join B (natural 不可以省略)。他们所得的结果中,同名且属性相同的字段只显⽰⼀个。
5. using⼦句的⽤法
using⽤于2张表的join查询,using⼦句可以指定⽤⼏个相同的名字和数据类型的列作为连接条件。
select * from table1 join table2 using(列名) 。
SELECT * FROM emp join dept using (deptno)
6. using ⼦句和等价连接的区别
using也是将2个表中属性列名相同的字段连接起来,不同的是等价连接是将所有的相同的都连接,⽽using(字段名)是将需要的字段连接起来(可以不是全部相同的)。
7. ⽐较下⾯的⼏个语句。
1 SELECT * FROM emp JOIN dept
2 SELECT * FROM emp NATURAL JOIN DEPT
3 SELECT * FROM emp JOIN dept USING (DEPTNO)
4 SELECT * FROM emp JOIN dept on emp.DEPTNO = dept.DEPTNO
语句1 是笛卡⼉积,所得结果为2张表的记录数乘积。 脑部结果。
join和in哪个查询更快
语句2和3,这⾥都是同⼀个结果如图,但是当emp表和dept表中有2个相同的列时候,他们结果就不⼀样了。这⾥就不演⽰了。
语句4 是等价连接。结果如图,它没有去掉重复的列。
8. 左外连接 left outer join … on …
左边的表是基本表,将左边的表的信息全部显⽰(不论是否可以有匹配,即为空也显⽰)。
SELECT * from emp e LEFT outer join dept d on e.DEPTNO=d.DEPTNO
9. 右外连接 right outer join … on …
右边的表是基本表,将右边的表的信息全部显⽰(不论是否可以有匹配,即为空也显⽰)。
SELECT * from emp e right outer join dept d on e.DEPTNO=d.DEPTNO
10. group by 分组
写在前⾯,sql关键词的执⾏顺序 :
from>where>group by>having>select>order by
group by (字段)是将表中的字段按照需求进⾏分组。通常与分组函数进⾏联合使⽤。
⼀般来说,select语句中,除了5个分组函数,其余出现的列名必须在group by⼦句中。
group by 语句中的列名不⼀定要出现在select语句中。
如果条件需要⽤到分组函数,则条件需要写在having⼦句中。
分组条件⼀定要有意义。
查询出每个部门的最低最⾼⼯资
SELECT DEPTNO ,min(SAL),max(SAL) FROM emp GROUP BY DEPTNO
思考:查询出每个部门的最低最⾼⼯资,同时查出此⼈的姓名?
1 查出每个部门的最低⼯资
2 将emp表与其做连接
⽅法1
SELECT e.DEPTNO,e.ENAME,e.SAL FROM emp e JOIN (SELECT DEPTNO ,min(SAL) minsal FROM emp GROUP BY DEPTNO)a on (e.DEPTNO=a.DEPTNO and e.SAL=a.minsal)
⽅法2
SELECT * FROM emp WHERE (DEPTNO,SAL) in (SELECT DEPTNO,min(SAL) FROM emp GROUP BY DEPTNO) 2次匹配,第⼀次匹配deptno,第⼆次匹配sal。列的属性得与in()⾥⾯的列属性相同
11. having⼦句
having是⽤于筛选信息的,匹配。
Having关键字的作⽤则是,为聚合结果指定条件。
12. 分组查询的嵌套
注意:当使⽤嵌套时,不能出现其他列名
13. ⼦查询
注意⼦查询的结果到底是1个值还是多个值,多个值时候可以⽤any或者in或者all。
⼦查询优先于外部查询。
单⾏⼦查询:⼦查询结果只有⼀个值。⼀般使⽤> = < 。
多⾏⼦查询:⼦查询结果有多个值。使⽤any,in not in,all。
14. 试题练习
⼀、查询出最低⼯资是2000的部门是那个?以及下⾯3句的区别?
① SELECT DEPTNO,min(SAL) FROM emp
②SELECT DEPTNO,min(SAL) FROM emp GROUP BY DEPTNO
③SELECT DEPTNO,min(SAL) FROM emp GROUP BY DEPTNO HAVING min(SAL)=1000
①是查询出最低⼯资的部门是哪⼀个。
②是查询出每个部门的最低⼯资。
③是查询出那个部门的最低⼯资是1000的。
⼆、查询部门⼈数⼤于所有部门平均⼈数的的部门编号,部门名称,部门⼈数
SELECT d.DEPTNO,d.DNAME,COUNT(d.DEPTNO)
FROM
emp e join dept d on d.DEPTNO=e.DEPTNO
GROUP BY d.DEPTNO,d.DNAME
HAVING
count(d.DEPTNO) >
(SELECT (SELECT COUNT(*) FROM emp) / (SELECT count(*) FROM dept ) )

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。