2021年11月20日 周六 写于 上海 和平公园
刚刚还小激动了一下,看到消息上有一个关注,赶紧翻看了一下,才发现还是2019年的一位朋友的关注,顿时归于平静。如果有人关注我,我还是愿意写一篇博客分享的,毕竟对于一件新鲜的事情 又具有意义的事情,大家还是乐于去做的。不废话了,乘着刚刚发现有人2年前对我的关注的热度和为了关注想写一篇博客的动机还在,写一篇博客,记录一下。
数据库sql 的执行顺序,如果你经常写sql,你也会经常去思考这个问题,毕竟还有人偶尔面试遇到过。这个还有人可能就是我,具体我也忘了,毕竟平时都是工作。面试过啥真的记不住,我就是属于解决问题能力不错,记性不好的程序员。
废话不多说:先上干货。
from -> where
->group by -> having
->select
->order by -> rownum | limit
有经验的人,看我的分行,可能就猜到我要说什么了。
简单说: 就是从一个大范围 不断缩小范围的过程,且有一点写代码从上到下,执行脚本的感觉。
from 先确定一张表,对吧,where条件限定一下,找那些数据。第一层范围确定。
第一层范围确定了,你可能要从某个或者某几个字段组 为分组维度进行group by ,分组group by后,再从分组维度上对数据进行 having 筛选,第二层缩小或者说确定一下范围。( 在select 上用某些聚合函数对数据进行聚合 -- 这是后话。)
然后select 执行,select 哪些字段,从垂直方向进一步缩小范围。
这些数据都确定下来了,然后order by 才有意义。order by 确定下来了,limit 出来的才正确。
如果没有order by ,你先limit ,你肯定属于小范围 order by ,肯定影响结果。
所以,这样的执行顺序很符合正常逻辑。
因为有这样的顺序存在,就自然而然地解决了很多问题。比如:一层select 语句中的 字段 as 别名之后,在where 中不能使用。因为where 先执行啊。那怎么办,把它搞到from 里面就可以了。就像下面的SQL, 这个grade 别名,你真心想要,你就套from 后面让 grade 变量声明执行早于你使用的使用。所以我就说和执行脚本很像。
select t.grade,count(1) -- 聚合函数,使用地方在select 上。
from (
select SAL,
(case
when sal<= 1000 then '0000-1000'
when sal<= 2000 then '1000-2000'
when sal<= 3000 then '2000-3000'
when sal<= 4000 then '3000-4000'
when sal<= 5000 then '4000-5000'
else '普通收入' end ) as grade
from EMP
) T where 1 =1
group by T.grade ; -- having 跟where 条件的,
看到了很多帖子说 select 在 order by 之后,我擦,我就真的不懂了。难不成 我这样经常实战写sql的程序员要向你缴纳智商税了 ? 感觉就很扯,我没怎么查过资料,但是我相信 select 肯定是在order by 之前 执行的,不然,select 面的别名,为什么可以 在order by 中使用,你能给 解释一下吗?
对了,我又想到在表关联的时候,on 里面的条件和where 条件的顺序问题,这个问题,我理解是,先关联到表数据,数据库会生成临时表,然后用on条件在临时表中缩小范围。where 条件中肯定用到 where tb1.xxx = '',根据这种语法,应该是从临时表空间操作数据列。所以先on,再where.
感谢2019年,关注我的朋友,我2021年才看到。谢谢你的关注,让我写了这篇,这篇小心得送个你,同时送你一颗小心心。我跑你贴吧上看了一下,空空如也,写博客这种苦差事,毕竟比较需要耐心。写的好简单哦,技术这种东西还是要经常编码才能找到感觉的。不说了,希望大家一路顺风,获得强大的编码能力。因为除了学习理论,强大的编码能力也很重要(遇到过某些我的上级以不写代码为荣,我都长期研究算法了,你连代码都不想写了,很奇怪你为什么骄傲,还是你骨子里很自卑,弱的写不了代码,哈哈)。此2者是相互促进的。不说了,我去同济大学那块去散步去了。