别名的妙用与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后面不太冗长

要把多表查询玩出花来 必须得会取别名

对过程有了个大致的理解 其实不难看出 提高效率还有一个方面

尽量减少表的连接次数 连接越多 要进行的遍历就越多 效率越低

image-38ffaae3

该执行的都执行了 只不过是把结果四选一

前面内连接里的自连接也用到了别名的概念

对于这样一张表

image-555fa9b7

存储了所有员工 员工信息后面又对应了其领导的编号

那么想查询员工名对应的领导名怎么办

把一张表看成两张表 看成emp a 员工表 emp b 领导表

image-72e30d10 image-b43a53ec
Select a.ename as '员工名',b.ename as '领导名'

from emp a join emp b

on a.mgr = b.empno(员工的领导编号等于领导的员工编号)

用别名 将表当成两个表 将mgr字段与empno字段进行连接

它其实就是一张表 但如果不使用别名

我们就无法去进行一个a.mgr = b.empno

image-411b1591

这个查询结果其实不全

因为king没有领导了 想要显示king怎么办

用到外连接

Select

a.ename as '员工名',b.ename as '领导名'

From

emp a

left join

emp b

on

a.mgr=b.empno
image-c1045442

把员工表a(其实就是emp整个表)作为主表(它在left的左边)

显示表a里所有的字段 把b表符合a.mgr=b.empno的字段加入这个表结构显示

但是 king不满足 那么就补充了NULL

“捎带”

嵌套查询中也有很多例子 像这个from子句中的子查询

一个遗留问题

image-dcbcde82
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-导入导出