可以说每个挨踢程序猿没有谁不知道SQL的,而且大部分人貌似都觉得这门语言很简单,只要知道自己要从哪拿点什么数据就是会写SQL,所谓的SQL高手可能就是多知道些函数,知道怎样在各种关系引用复杂的表中把想要找的东西给翻出来,而且能把SQL写成论文,自己都看不明白。(这么说貌似有点否定了好多人,好像满天的草泥马飞过)
SQL想写好其实不难,而且会发现一片新大陆,但是,对程序猿来说需要有一种思想上的转变,就好像学了金钟罩之后又来学太极似的,思想上一个是以刚硬抵御一切,一个是以柔克刚,到底谁能打过谁?可能最终的结论是天下武功唯快不破?不管是金钟罩也好,太极也好,能快点把对手干趴下,那就是牛逼呀!好吧,其实这也跟程序的性能挂上钩,编程算法虽然能优化程序的性能,但是,从数据库里拿出一大堆数据的过程中,就算用再好的算法去处理其实没啥意义,这个过程当中数据库里从硬盘读到内存,再传到程序里处理的过程已经耗费了大把大把的时间,倒不如在数据库里处理好了,就拿一点点处理好的结果给程序来得高效,至于能在数据库里以什么样的速度处理多少量的数据,那就得看SQL能写到啥程度了。而啥时候在数据库里处理,啥时间靠编程或算法解决就是一个衡量和取舍的问题了。
那么,整理一下SQL高手的标杆是啥?两点:
- 在数据库里用SQL变着花样处理数据
- 保证SQL执行的性能达到最优
要做到这两点难不难?这个问题不好回答。
有没有快速成为高手的捷径?这个可以有。
之前说了SQL想写好需要程序猿们转变思想,其实大部分人也多多少少能从网上查到,很多书里也介绍过,SQL需要集合处理的思维,这跟程序里的按照顺序和流程处理的思维稍微有点不一样了。
啥是集合思维?简单点说就是每次处理都是一堆,后一次处理引用不了上一次处理的结果,顺序处理就是一次一个地处理,后一次处理可以引用前一次处理的结果。这样讲有点理解不了?看一下吧,假如有下面一张表,我要对col1这个字段累计求和,编程语言咋写,SQL咋写?
col1
------
1
2
3
4
5
用编程语言的话,无非就是先个循环调用每一行,也就是一行一行的读出来,再声明个变量,反复叠加每行值最后得到一个总数。
结果如下:
col1 col2
----- -----
1 1
2 3
3 6
4 10
5 15
那用SQL咋写?SQL里的循环语句是啥?哈哈
高手估计能相处好几种方法来,好吧,确实是有好几种办法,但是,我想说的是在SQL扩展函数还没那么多的时候,用的最单纯的方法!
先看看这样一个表,如果col1和col2以这样一种格式出现,是不是能有点灵感?
col1 col2
------ -----
1 1
2 1
2 2
3 1
3 2
3 3
4 1
4 2
4 3
4 4
5 1
5 2
5 3
5 4
5 5
看一下这个表里的数据,可以看出来,这里面可以以col1的值分成5组,每组的col2里都包含了小于等于自己的值,然后把每组值在col2里的值加到一起是不是就相当于重复地叠加了各个值?是不是结果就跟前面的结果是一样的?
那怎么把第一次表中的值变成第二个表里的值呢?这就需要找集合了,这个表与自己比对,从里面的找到比自己小或等于自己的所有值即可!来一段SQL看看吧?
select a.col col1
, b.col col2
from tab a, tab b
where a.col > = b.col
多少写过SQL的童鞋很容易理解这段代码吧?脑子里想想执行的过程是啥,每个过程的数据都是啥?很简单吧?
基于这个结果集,再用个聚合函数,是不是就出来累计合了?上代码!
select col1
, sum(col2)
from (
上面那段代码
)
group by col1
OK了吧?光说不练假把式~赶紧动手吧。湿完了再看下面的。
SQL的写法比较多,对于这个问题,用一种更接近程序猿的写法看看。
select col1
, (select sum(col1)
from tab b
where b.col1 <= a.col1) col2
from tab a
稍微学点SQL就知道这里用了标量子查询,这种方法虽然也是集合思维,执行的过程很容易想像成每处理一行都把当前行的值代入标量子查询之后直接求和后返还。
最基本的两种方式,都体验过啦,稍微对集合思维有点感觉了么?没有?好吧,以后慢慢多看多写吧。 至于其他方法,且听下次分解吧。
网友评论