MySQL进阶之路八(高级查询)

1.高级查询(多表查询)
#查询员工编号(empno,emp表)为9527的员工姓名(ename,emp表)和所在部门名称(dname,dept)
select ename from emp  where empno = 7788;#查姓名
select dname from dept where empno ==7788;#查部门
#一.内连接(没有主从表之分)
select ename ,dname from emp,dept where emp.deptno =dept.deptno;
#2.内连接,通用列会出现2次
select *from emp 
inner join dept 
on empt.deptno = dept.deptno;
#3.内连接  #using(通用列) 通用列关联字段必须相同,通用列不会出现2次
select * from emp
inner join dept 
using (deptno);

#查询学生编号为1 所在班级(class表)和学生名称(student表),学生钱数(student表)
select s.sid,s.sname,s.money,c.cname  from student s,class c where s.cid = c.cid and sid =1;

select * from student 
inner join class 
on student.cid = class.cid ;

select * from student 
inner join class 
using(cid);
关联表中都出现的字段信息最终才会显示在结果集中
内连接与连接顺序无关

#二。外连接(有主从表之分,与连接顺序有关)
一次遍历主表中的记录,与从表中的记录进行匹配,如果匹配到则连接展示,否则以null填充
1.左外连接  left [outer] join  ...on
2.右外连接  Right [outer] join ... on

#左连接:将左表当做主表,依次遍历和从表建立关联
#查询员工编号(empno,emp表)为9527的员工姓名(ename,emp表)和所在部门名称(dname,dept)
select *from emp 
left join dept 
on emp.deptno = dept.deptno; #eno为主表,dept为从表

#查询学生编号为1 所在班级(class表)和学生名称(student表),学生钱数(student表)
select * from student
left join class
on class.cid = student.cid; #student 为主表,class为从表

select * from class
left join student
on class.cid = student.cid; 

select * from class 
right join student 
on class.cid = student.cid ;#右连接,student为主表,class为从表
#等值连接
特殊 #自然连接 ,肯定是等值连接(字段名称必须相同),但等值连接不一定是自然连接
select * from emp natural join dept;
select * from student  natural join class;

#自连接
#查询说有员工和领导的姓名(在同一张表中)
select e1.ename 雇员, e2 ename 领导 from emp e1,emp e2
where e1.mgr = e2.empro;
#外连接
select e1.ename 雇员, e2 ename 领导 from emp e1
left join emp e2
on e1.mgr = e2.empro

#如果cid 为null 就会不显示该数据
select s1.sname 名字,s2.cid 班级id from student s1,student s2 
where  s1.sid = s2.cid;
#如果cid 为null 也会会不显示该数据
select s1.sname 名字,s2.cid 班级id from student s1
left join student s2
on s1.cid = s2.sid;

show variables like '%char%';#查看当前编码

#1.查询平均工资最高的部门的部门名称和平均工资
#1 连接, 平均工资
select dname,avg(sal) from emp,dept  
where emp.deptno = dept .deptno   #关联表
group by emp.deptno  #按照部门id进行分组
order by avg(sal) desc #平均工资进行排序
limit 0,1 #取第一个
#1.2 先求平均工资最高的部门,求部门名称
select dname ,e.`avg` from dept, #和工资最高的进行关联查询 (
select deptno,avg(sal) `avg` from emp #查询部门最高工资,当做集合
group by deptno 
order by `avg` desc 
limit 0,1) e  
where dept.deptno = e.deptno;

#1.3 
select max(a.avg) from (
select deptno,avg(sal)  `avg` from emp
group by deptno) a,			#部门平均工资

#2.查询工资>2000 且不再20号部门的员工的姓名和所在部门信息
select * from dept ,(
select * from empt
where sal >2000 and deptno <>20);

#3.查询薪水大于scott的员工信息和所在部门信息
#3.1  Scott薪水
select sal from emp where ename ='scott';
#大于Scott薪水的员工信息
select * from emp where sal > #主查询
(
select sal from emp where ename ='scott'   #子查询
) ;

#4.查询Scott 在同一部门的所有员工信息
select * from emp where deptno =(
select deptno from emp where ename ='scott'
)

#子查询(嵌套查询):讲一个查询的结果当做另一个查询的调节或结果集
子查询是最接近思考方式,最自然的查询
#分类, 1单行子查询,2多行子查询
单行子查询:子查询返回结果只有一条记录
#查询薪水大于scott的员工信息和所在部门信息
#3.1  Scott薪水
select sal from emp where ename ='scott';
#大于Scott薪水的员工信息
select * from emp where sal > #主查询
(
	select sal from emp where ename ='scott'   #子查询
) ;

多行子查询:子查询返回结果有多条记录 in , any   , all, 
 =any 相当于in , >any 大于最小值, <any 小于最大值
 > all  大于最大值,<all 小于最小值 
 
#查询薪水和20号部门员工相等且不再20好部门员工信息
select * from emp where sal in(
	select distinct sal from emp 
	where deptno =20
	) and deptno != 20;

#查询20号部门除了工资最高的员工信息
select * from emp where sal <any(
select sal from emp 
where deptno =20
)
and deptno =20;


#5查询大于20号部门的平均工资的20号的员工信息
select * emp where sal > (
select avg(sal) from emp 
where deptno = 20
) 
and deptno =20;

#6查询大于所在部门平均工资的所有员工信息
select deptno, avg(sal) from emp group by deptno; #每个部门平均工资

select * from emp ,(
select deptno, avg(sal) `avg` from emp 
group by deptno
) e 
where emp.deptno = e.deptno and sal > e.avg;

select * from emp e where sal>(
select avg(sal) from emp e1 where e1.deptno =e.deptno
)
#1主查询遍历整个emp表
#2.主查询读取某一条记录的deptno的值,将该值交给子查询
#3子查询根据主查询传来的deptno查询出指定部门的平均工资然后将整体结果返回给主查询
#4主查询根据子查询的结果最终执行

#7查询工资>20号部门的所有员工信息
select * from emp where sal >(
select max(sal) from emp where deptno =20;
) deptno != 20;

select * from emp where sal >all(
select distinct sal from emp where deptno =20
) deptno !=20;

#8查询薪水>2000 的员工所在部门的信息
#8.1关联查询
select dept * from emp, dept 
where emp.deptno = dept.deptno and sal >2000;
#8.2子查询
select distinct deptno from emp where sal >2000;#查询薪资大于2000的员工部门编号
#in /=/>/< 主查询和子查询  deptno和子查询中的字段必须相同
select * from dept where deptno in(
select distinct deptno from emp
where sal >2000
);
#exists  
select * from dept where exists
(select * from emp where sal >2000 and dept.deptno =emp.deptno)
#in 和exists的区别
#in 先执行子查询 ,将结果返回给主查询, 主查询继续执行
#exists 先执行主查询,将主查询的值依次在子查询中进行匹配,根据是否匹配返回true 或者false,如果是true值连接展示,否则不展示

#多表和子查询
#子查询---> 查询条件和结果放在一张表里(最终查询结果分布在多张表中,尽量使用多表查询)
#关联查询:表太大不适用,能够处理结果在多表中,但是占用内存比较大

#三。联合查询(索引,Or会导致索引失效)联合结果集必须一致
关键字(union(会去重) ,union all(不会去重))
#9查询20好部门以及工资大于20的员工信息
select * from emp where deptno =20 or sel>2000;

select * from emp where deptno = 20
union 
select * from emp where sel >2000


猜你喜欢

转载自blog.csdn.net/ZhaiAlan/article/details/92808614