Mysql数据库笔记(3)

本文详细介绍了数据库查询中的子查询用法,包括在where、from和select后的子查询应用,以及如何解决子查询中遇到的问题。通过案例展示了如何找出比最低工资高的员工、计算每个岗位的平均工资并分配薪资等级,以及实现分页查询和合并查询结果。同时,讨论了union操作的效率和限制,以及limit在分页查询中的作用。最后,总结了DQL语句的执行顺序。
摘要由CSDN通过智能技术生成

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

子查询都可以出现在哪里?
select
	...(select)
from 
	...(select)
where
	...(select)
  • where语句中的子查询

  •   案例:找出比最低工资搞得员工姓名和工资?
      select
      	ename,sal
      from 
      	emp
      where 
      	sal > min(sal);   //会报错
    

    where子句中不能直接使用分组函数

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

from子句中的子查询

注意:from后面的子查询,可以将子查询的查询结果当作一张临时表。

案例:找出每个岗位的平均工资的薪资等级
第一步:找出每个岗位的平均工资(按照高位分组求平均值)
select job,avg(sal)from emp grup by job;
 job       avg (sal)
 ANALYST   300o. ooo000 
 CLERK     1037.50000o 
 lMANAGER  2758.333333 
 PRESIDENT 5000. o000oo
 SAL,ESMAN 140o. oooo0o 
+-----------4-------------+t表

第二步:克服心理障碍,把以上的查询结果就当作一张真是存在的表t
select * from salgrade;   //s表

GRADE lLOSAL lHISAL
 1     700 	  1200								
 2     1201   1400								
 3     1401   2000								
 4     2001   300o							
 5     3001   9999
------------                                  s表的losal和s表的hisal
t表和s表进行表连接,条件t表中的avg(sal) between s.losal and s.hisal;

select 从t表中查所有,s表中查grade
	t.*, s.grade
from  从t表查
	t
join  t表和这个表链接
	salgrade s
on  条件:t表的avg(sal)字段 between s表中的losal字段 和 s表中hisal字段;
	t.avg(sal) between s.losal and s.hisal;
结果会报错,原因是t表不存在

正确语句
select 
	t.*, s.grade
from                   该别名avgsal
	(select job,avg(sal) as avgsal from emp group by job) t
join
	salgrade s
on
	t.avgsal between s.losal and s.hisal;

+-----------+-------------+-----―
ljob          avgsal        grade 
CLERK         1037.50000o    l
SALESMAN      1400.00000o    2 
ANALYsT       300o. ooo0oo   4 
MANAGER       2758.333333    4 
lPRESIDENT    5000. oooooo   5 
+-----------+-+-------+

select后面出现子查询

案例:找出每个员工的部门名称,要求显示员工名,部门名?
select 
	e.enam,e.deptno,(select d.dname from dept d where e.deptno = d.deptno)as dname 
from 
	emp e;
	
ename  deptno  ldname
1--------+--------+------------+
SMITH   20    lRESEARCH
ALLEN   30    SALES
WARD    30    SALES
JONES   20 	  RESEARCH
MARTIN  30    SALES
BL.AKE  30    SALES
CL.ARK  10    ACCOUNTING
sCoTT   20    RESEARCH
KING    10    ACCOUNTING
TURNERl 30    SALES
ADAMS   20    RESEARCH
JAMES   3o    SALES
FORD    20    RESEARCH
MILLER  10    ACCOUNTING

select 
	e.enam,e.deptno,(select dname from dept)as dname 
from 
	emp e;
注意:对于select后面的子查询来说,这个子查询只能一次返回1条结果,对于一条,就报错。

union合并查询结果集

案例:查询工作岗位是MANAGER和SALESMAN的员工
select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
同于select ename,job from emp where job in ('MANAGER','SALESMAN');

select ename,job from emp where job = 'MANAGER'
union 
select ename,job from emp where job = 'SALESMAN';

union的效率要高一些。对于表连接来说,没链接一次新表,
则匹配的次数满足笛卡尔积,成倍得翻。
但是union可以减少匹配的次数。

union在使用的时候有主意事项吗

错误的:union在进行结果集合并的时候,要求两个结果集的列数相同。
select ename,job from emp where job = 'MANAGER'
union 
select ename from emp where job = 'SALESMAN';  //会报错

mysql可以,oracle语法不可以,要求:结果集合并时列和列的数据类型也一致。

select ename,job from emp where job = 'MANAGER'
union 
select ename,sal from emp where job = 'SALESMAN';

limit

limit是将查询结果集的一部分取出来,通常使用在分页查询当中。
	百度默认:一夜显示十条记录。
	分页的作用是为了提高用户的体验,因为一次全部都查出来,用户体验差。
	可以一页一页翻页看。
	
limit怎么用?
完整用法:limit startindex,length
		startindex是起始下标,length是长度
		起始下标从0开始。
	缺省用法:limit 5;  //这时取前5
	按照薪资降序,取出排名在前5名的员工。
	select 
		ename,sal
	from 
		emp 
	order by 
		sal desc
	limit 5;  //取前五
	
注意:mysql当中limit在order by之后执行!!!

取出工资排名在[3-5]名的员工
	select 
		ename,sal
	from 
		emp
	order by 
		sal desc
	limit 
		2,3;
	2表示起始位置从下表2开hi,就是第三条记录
	3表示长度

取出工资排名在[5-9]名的员工
	select 
		ename,sal
	from
		emp
	order by 
		sal desc 
	limit
		4,5;

分页

每页显示3条记录
	第一页:limit 0,3   [0 1 2]
	第二页:limit 3,3   [3 4 5]
	第三页:limit 6,3   [6 7 8]
	第四页:limit 9,3   [9 10 11]
	
每页显示pagesize条记录
	第pageNo页:linit (pageNo -1) * pagesize , pagesize
	
	public static void mian(steing[] args){
	// 用户提交过来一个页码,以及煤业显示的记录条数
	int pageNo = 5; //第5页
	int pagesize = 10; //每页显示10条
	
	int starindex = (pageno - 1) * pagesize;
	string sql ="select ...limit" + starindex + "," + pagesize;
	}
记公式:
	limit (pageNo-1)*pagesize,pagesize

关于DQL语句大总结:

select
	...
from 		
	...
where 		
	...
group by 	
	...
having		
	...
order by 	
	...
linit 
	...
	
执行顺序:
1.from 		
2.where 		
3.group by 	
4.having		
5.select
6.order by 	
7.limit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值