别名的妙用与limit分页
*别名的妙用
对比三条sql语句
(1)Select ename,dname from emp,dept where emp.deptno=dept.deptno
(2)Select emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno
(3)Select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno
功能一样 把职工表和部门表连接 找每个人所在的部门的名字
先回顾一下select进行的流程
拿着一个字段 遍历整个表 把它找出来 重点:遍历整个表
把两个表连接了也是一样
像第一种写法
经过的步骤是
拿着ename这个字段 从emp里面找 找到了
但是还没完 它还要去dept里去找这个ename字段 其实dept里压根没这个字段
做了无用功
dname同理 在emp表里做了无用功
白白把两个表都多遍历了一遍
这都是因为 ename和dname没有标明属于哪个表
所以有了第二种写法
这样emp.ename只要遍历emp表 dept.dname只要遍历dept表
效率提高了
Select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno
用语句执行顺序分析
From emp和dept表 给emp表取别名叫e 给dept表取别名d(别名的AS 是可以省略的)
WHERE 拿着表e的每一条记录 分别去与d表的每条记录匹配 匹配到deptno相同的就保留
Select 从e表中拿ename,d表中拿dname 进行一个组合 并显示出来
内部做的工作其实跟第二种一样
只是这个例子不能很好的显示出别名的妙用 只能说使得select后面不太冗长
要把多表查询玩出花来 必须得会取别名
对过程有了个大致的理解 其实不难看出 提高效率还有一个方面
尽量减少表的连接次数 连接越多 要进行的遍历就越多 效率越低
该执行的都执行了 只不过是把结果四选一
前面内连接里的自连接也用到了别名的概念
对于这样一张表
存储了所有员工 员工信息后面又对应了其领导的编号
那么想查询员工名对应的领导名怎么办
把一张表看成两张表 看成emp a 员工表 emp b 领导表
Select a.ename as '员工名',b.ename as '领导名'
from emp a join emp b
on a.mgr = b.empno(员工的领导编号等于领导的员工编号)
用别名 将表当成两个表 将mgr字段与empno字段进行连接
它其实就是一张表 但如果不使用别名
我们就无法去进行一个a.mgr = b.empno
这个查询结果其实不全
因为king没有领导了 想要显示king怎么办
用到外连接
Select
a.ename as '员工名',b.ename as '领导名'
From
emp a
left join
emp b
on
a.mgr=b.empno
把员工表a(其实就是emp整个表)作为主表(它在left的左边)
显示表a里所有的字段 把b表符合a.mgr=b.empno的字段加入这个表结构显示
但是 king不满足 那么就补充了NULL
“捎带”
嵌套查询中也有很多例子 像这个from子句中的子查询
一个遗留问题
from
sc,(select sno,avg(grade) from sc group by sno) as avg_sc(avg_sno,avg_grade)
Where
sc.sno = avg_sc.avg_sno
And
grade > avg_sc.avg_grade
分析一下其实也很清晰 从sc和这个虚拟表里查 但是这个虚拟表有两个字段
把它取个别名 整个表叫avg.sc 表里的sno字段叫做avg_sno avg(grade)字段叫avg_grade
可以当成这样:
sc,(select sno as 'avg_sno',avg(grade) as 'avg_grade' from sc group by
sno) as avg_sc
不过长知识了 还能用这种很像结构体的写法 avg_sc(avg_sno,avg_grade)
后面就很简单了 一个where筛选两个条件 就是把sc和这个虚拟表做个连接而已
所以现在看来别名的妙用:
使得代码不冗长简洁 但可读性会变差(不好理解)
使得代码执行效率更高
是某些操作(如自连接)的必要条件
子查询中为虚拟表命名以迎合自己的查询思路(如果给你两个存在的表那么很清楚应该怎么查 但如果是对一个查询结果进行操作 就有点懵了 所以用别名 把它当成真实存在的表)
别名的概念不仅在sql中体现 像c语言和数据结构中的typedef
都是一些操作的关键要素
limit分页
像百度等搜索引擎 查询出来的东西都是有分页的 limit就是限制结果的数量 达成分页效果
limit startIndex,length 起始下标、长度
select ename,sal from emp order by sal desc limit 5 缺省 取前五个
相当于
select ename,sal from emp order by sal desc limit 0,5
limit在order by后面执行
取工资在3~5名的员工 起始下标是0 0 1 2 3 4 2开始 取长度3 所以2,3
select ename,sal from emp order by sal desc limit 2,3 如果[5~9] limit4,5
每页显示3条记录
第一页:limit 0,3 [012] 第二页limit 3,3 [345] 第三页limit 6,3 [678]
每页显示pagesize条记录
第pageno页:limit ?,pagesize
?(startIndex)等于(pageno-1)*pagesize
如何实现浏览器一样 点击哪页就显示哪页数据
相当于是用户给出一个页码 又已有每页显示的记录条数
可以封装成
public static void main(String[] args)
{
int pageNo=5;
int pageSize=10;
int startIndex=(pageNo-1)*pageSize;
String sql="select … limit"+startIndex + "," + pageSize;
}
记limit (pageno-1)*pagesize,pagesize
大总结
from where group by having select order by limit
通过from查 用where进行筛选 筛选完了分组 分组后过滤
过滤后查出来 排序输出 排序后可能要取段 分页展示
⬅️ 14-子查询与结果集归并 🏠 00-数据库 ➡️ 16-导入导出
💬 评论