大家来学数据库(非学院派,实战派修炼法)
之前提过,很长时间以来,非IT专业学生基本都不学数据库,甚至连选修的机会都没有。倒是没有技术含量的办公自动化大行其道,导致当今绝大多数白领都只会玩Excel之类的傻瓜机,这是白领工作效率低下的重要原因,也是后来者有望弯道超车的好机会。
不过即使真的开数据库课程,也未必是好事。数据库如果按照大家熟悉的学院派教法,估计很多人会从兴致盎然到兴味索然甚至苦不堪言。我们不妨另辟蹊径,来一场实战派修炼。也许大家会惊讶地发现,原以为数据库很难,没想到可以这么简单!
怎么开发数据库管理系统,那是大佬的事。微软的SQL SERVER是现在主流的数据库,我们说的学数据库,只是学习在上面开发自己的应用,难度并不高。如果把SQL SERVER比作巨人,那SQL语言就是阿拉丁的神灯,只要学会SQL语言,就可以指挥巨人呼风唤雨移山填海。SQL语言是所有跟计算机打交道的语言中最接近自然语言的,对于英语基础不错的大学生来说,简直就是大白话(哑巴英语也可以派上大用场了)。因此,我们的实战派修炼,不谈理论,也不谈概念,直接从SQL语言切入。
不过即使真的开数据库课程,也未必是好事。数据库如果按照大家熟悉的学院派教法,估计很多人会从兴致盎然到兴味索然甚至苦不堪言。我们不妨另辟蹊径,来一场实战派修炼。也许大家会惊讶地发现,原以为数据库很难,没想到可以这么简单!
怎么开发数据库管理系统,那是大佬的事。微软的SQL SERVER是现在主流的数据库,我们说的学数据库,只是学习在上面开发自己的应用,难度并不高。如果把SQL SERVER比作巨人,那SQL语言就是阿拉丁的神灯,只要学会SQL语言,就可以指挥巨人呼风唤雨移山填海。SQL语言是所有跟计算机打交道的语言中最接近自然语言的,对于英语基础不错的大学生来说,简直就是大白话(哑巴英语也可以派上大用场了)。因此,我们的实战派修炼,不谈理论,也不谈概念,直接从SQL语言切入。
考虑到大家多半没有安装SQL SERVER,我们就举最简单的例子,从最容易的SQL语句开始,配上结果图,让大家慢慢找感觉。等有了兴趣,再做深入学习的打算。现在这里已经创建好了一张表A1,只有一个字段Z1(数值型),里面只有简单的几个数字。到底里面有些什么?在Excel里,打开一个文件,点开某个工作表,就可以看到内容,对数据库来说,提取表的内容,要这样下指令:
Select Z1 from A1
意思是从A1表中取Z1字段。有些人可能一说写语句就发怵,以为很难很高深,但你看看这个语句,是不是就跟大白话差不多?
Select Z1 from A1
意思是从A1表中取Z1字段。有些人可能一说写语句就发怵,以为很难很高深,但你看看这个语句,是不是就跟大白话差不多?
有了这2张最简单的表,我们就可以开讲数据库中最重要的操作——连接。很多人一开始就把连接想歪了,以为连接就是以一张表中的特征值到另一张表中取相关的属性值,比如用产品的代码到产品表中取它的名称及大小重量等属性。一一对应找东西确实是连接的一种用法,却不是连接的本意。连接的本意是交叉配对,就是说一张表的每一条记录都跟另一张表的每一条记录进行配对,这里A1表8条记录,A2表5条记录,交叉连接的结果是8*5=40条,这没什么。如果两张表各有上千,结果就超过百万条,那就很可怕了。因此交叉连接实际几乎不会用到,但理解了它才真正领悟到数据库的精髓。交叉连接的标准写法是:
select Z1,Z2 from A1 cross join A2,
相信大家会更喜欢更简洁的偷懒写法:
select Z1,Z2 from A1,A2(中间用逗号代替)
结果40条有点太多,只截取头尾2张图,中间大家脑补:
select Z1,Z2 from A1 cross join A2,
相信大家会更喜欢更简洁的偷懒写法:
select Z1,Z2 from A1,A2(中间用逗号代替)
结果40条有点太多,只截取头尾2张图,中间大家脑补:
*代表所有表的所有字段。
如果前面有表名加点,则表明是该表的所有字段。
因此,select * from A1,A2 跟上面的 select Z1,Z2 from A1,A2 是等价的,就不配图了。
同理,select A1.* from A1,A2 相当于 select Z1 from A1 重复5遍
如果前面有表名加点,则表明是该表的所有字段。
因此,select * from A1,A2 跟上面的 select Z1,Z2 from A1,A2 是等价的,就不配图了。
同理,select A1.* from A1,A2 相当于 select Z1 from A1 重复5遍
select * from A1 join A2 on A1.Z1=A2.Z2
这就是大家最熟悉,最常用的连接方式——内连接,也是默认的连接方式。。
与Excel里Vlookup不同的是,如果找不到A2表的对应记录,A1表的记录也会消失,这是初学者应该特别注意的。
很多初学者往往比照Vlookup来想象连接,默认的内连接恰好与之不同。连接方式用错必定导致报表结果出错。这是入门时期的常见问题,切记切记!
这就是大家最熟悉,最常用的连接方式——内连接,也是默认的连接方式。。
与Excel里Vlookup不同的是,如果找不到A2表的对应记录,A1表的记录也会消失,这是初学者应该特别注意的。
很多初学者往往比照Vlookup来想象连接,默认的内连接恰好与之不同。连接方式用错必定导致报表结果出错。这是入门时期的常见问题,切记切记!
我们再看一种写法:
select * from A1,A2 where A1.Z1=A2.Z2
这是前面提到的交叉连接加上条件,结果与刚才的内连接完全相同。
内连接与交叉连接加上相应的条件结果相同,这可以帮助我们理解,交叉连接才是连接的源头,内连接尽管用得更多,也尊为默认连接方式,但其实是由交叉连接加条件派生出来的。
where 后面带的是整个语句的条件,on 后面带的是2表间的连接条件,如果多个表连接,就会有多个on。
表间连接条件跟整体条件基本上等价,使用表间连接条件可以使关系更清晰,也使得整体条件不至于太杂乱。
select * from A1,A2 where A1.Z1=A2.Z2
这是前面提到的交叉连接加上条件,结果与刚才的内连接完全相同。
内连接与交叉连接加上相应的条件结果相同,这可以帮助我们理解,交叉连接才是连接的源头,内连接尽管用得更多,也尊为默认连接方式,但其实是由交叉连接加条件派生出来的。
where 后面带的是整个语句的条件,on 后面带的是2表间的连接条件,如果多个表连接,就会有多个on。
表间连接条件跟整体条件基本上等价,使用表间连接条件可以使关系更清晰,也使得整体条件不至于太杂乱。
select * from A1 left join A2 on A1.Z1=A2.Z2
这个是左连接,也很常用。
左连接不是默认连接,却是最符合Excel玩家习惯和想象的连接方式。很像那个著名的vlookup函数的表现。
它的意思是,不论是否找到与之匹配的对应记录,反正左表的记录全都要,没有匹配上的右表字段,只能放空(用空值表示),但不会报错,这一点与vlookup不同。
这个是左连接,也很常用。
左连接不是默认连接,却是最符合Excel玩家习惯和想象的连接方式。很像那个著名的vlookup函数的表现。
它的意思是,不论是否找到与之匹配的对应记录,反正左表的记录全都要,没有匹配上的右表字段,只能放空(用空值表示),但不会报错,这一点与vlookup不同。
有左连接,那么也应该有右连接。
右连接跟左连接正好相反,以右表为主表
因为左右表可自由调换,一般习惯上把主表放在左边,使用左连接。右连接相对用得少些(不排除有些人习惯使用右连接,不是还有左撇子么)。在多表连接时,有时候可能需要左右开弓,不过不建议把连接弄得很复杂,不如分步走。玩数据库,分步走是非常重要的基本策略,这个稍后再说。右连接就是把 left 改成 right,很简单:
select * from A1 right join A3 on A1.Z1=A3.Z3
右连接跟左连接正好相反,以右表为主表
因为左右表可自由调换,一般习惯上把主表放在左边,使用左连接。右连接相对用得少些(不排除有些人习惯使用右连接,不是还有左撇子么)。在多表连接时,有时候可能需要左右开弓,不过不建议把连接弄得很复杂,不如分步走。玩数据库,分步走是非常重要的基本策略,这个稍后再说。右连接就是把 left 改成 right,很简单:
select * from A1 right join A3 on A1.Z1=A3.Z3
select * from A1 full join A3 on A1.Z1=A3.Z3
这是最后一种连接方式——全连接,全连接就是不论是否对上号,左右两边一个都不能少,这应该也很好理解。
全连接往往被人忽略,需要的时候其实很好用。
对不知道有此连接方式的人来说,用变通方式实现这种效果,是要费些周折的。
连接是数据库的基础,对连接理解不清容易犯低级错误,不过也就这几个类型,没有多大难度。开始不要着急,把连接理解透彻,后面就好走多了。
连接是数据库的核心,也就这5种类型,最常用的其实就内连接与左连接,理解了连接,数据库的大门就已经敞开了。芝麻开门,数据库,我来了!
这是最后一种连接方式——全连接,全连接就是不论是否对上号,左右两边一个都不能少,这应该也很好理解。
全连接往往被人忽略,需要的时候其实很好用。
对不知道有此连接方式的人来说,用变通方式实现这种效果,是要费些周折的。
连接是数据库的基础,对连接理解不清容易犯低级错误,不过也就这几个类型,没有多大难度。开始不要着急,把连接理解透彻,后面就好走多了。
连接是数据库的核心,也就这5种类型,最常用的其实就内连接与左连接,理解了连接,数据库的大门就已经敞开了。芝麻开门,数据库,我来了!
select *,Z1+Z3 as [Z1+Z3] from A1 full join A3 on A1.Z1=A3.Z3
现在开讲字段运算。
连接后,不仅可以取任意表的任意字段,还可以对字段进行运算。表达方式是:先写公式,中间加 as,后面是新字段名。as 可以省略,字段名如果包含特殊字符或全数字,要加中括号,普通的字段名可以不加。
这里Z1、Z3都是数值型,因此加号就是相加的意思。可以使用 + - * /(加减乘除)各种运算符号,也可以使用函数。SQL Server 的内置函数没通常的编程语言多,勉强够用。
可能你注意到,结果中只有2表都有的才加和,任何一表没有就空白。这就是前面所说的空值及空值的运算特点。其实相加动作没有少,只是空值跟什么相加都是空值。初学者一定要特别注意。
现在开讲字段运算。
连接后,不仅可以取任意表的任意字段,还可以对字段进行运算。表达方式是:先写公式,中间加 as,后面是新字段名。as 可以省略,字段名如果包含特殊字符或全数字,要加中括号,普通的字段名可以不加。
这里Z1、Z3都是数值型,因此加号就是相加的意思。可以使用 + - * /(加减乘除)各种运算符号,也可以使用函数。SQL Server 的内置函数没通常的编程语言多,勉强够用。
可能你注意到,结果中只有2表都有的才加和,任何一表没有就空白。这就是前面所说的空值及空值的运算特点。其实相加动作没有少,只是空值跟什么相加都是空值。初学者一定要特别注意。
select *,isnull(Z1,0)+isnull(Z3,0) [Z1+Z3] from A1 full join A3 on A1.Z1=A3.Z3
为解决空值的困扰,可以用 isnull 函数,把空值转为0,这样相加就没问题了。
Isnull 函数,前面的参数是原值或字段,后面是对应值,可以是0,也可以是其它数字或文本。意思是,如果原值不是空值,就保持不变,如果是空值,就转变成对应值。
为解决空值的困扰,可以用 isnull 函数,把空值转为0,这样相加就没问题了。
Isnull 函数,前面的参数是原值或字段,后面是对应值,可以是0,也可以是其它数字或文本。意思是,如果原值不是空值,就保持不变,如果是空值,就转变成对应值。
select *,isnull(cast(Z1 as varchar(10)),'')+isnull(cast(Z3 as varchar(10)),'') [Z1Z3] from A1 full join A3 on A1.Z1=A3.Z3
对于文本来说,加号就表示拼接或相连。
Cast 函数表示转换类型,as 前面是原值或字段,后面是转换成的类型。
Varchar 表示变长度文本类型,括号内的数字是最大长度。如果长度小于最大长度,实际多少就多少,如果超出最大长度,也不报错,只返回星号(*)
对于文本来说,加号就表示拼接或相连。
Cast 函数表示转换类型,as 前面是原值或字段,后面是转换成的类型。
Varchar 表示变长度文本类型,括号内的数字是最大长度。如果长度小于最大长度,实际多少就多少,如果超出最大长度,也不报错,只返回星号(*)
select Z1,sum(Z2) SZ2 from A1,A2 group by Z1
分组汇总是很有用也很常用的功能。表示以Z1为分组依据,把Z2汇总。这有点类似于 Excel 里的 sumif 函数。每个 sumif 函数的结果约当于这里的一条。
由于采用交叉连接的结果作为原始数据,汇总值完全相同显得有些无趣。一般来说不会是这样整齐划一的。
分组汇总是很有用也很常用的功能。表示以Z1为分组依据,把Z2汇总。这有点类似于 Excel 里的 sumif 函数。每个 sumif 函数的结果约当于这里的一条。
由于采用交叉连接的结果作为原始数据,汇总值完全相同显得有些无趣。一般来说不会是这样整齐划一的。
select Z1,sum(Z2) SZ2,count(Z2) CZ2,min(Z2) MZ2,max(Z2) XZ2 from A1,A2 group by Z1
除了 sum,count 表示计数,min 表示最小,max 表示最大,都很好理解。Count 还比较常用,后两个就用得少些。
除了 sum,count 表示计数,min 表示最小,max 表示最大,都很好理解。Count 还比较常用,后两个就用得少些。
select Z2,sum(Z2) SZ2,count(Z2) CZ2,min(Z2) MZ2,max(Z2) XZ2 from A1,A2 group by Z2
如果把分组依据换成Z2,结果就大不一样了。
如果把分组依据换成Z2,结果就大不一样了。
关于SQL语句的实例,后续还将不断推出。其实只要很好理解了以上的语句,数据库的基础就打下了,看到相关代码就不会觉得是天书了。当然光凭这些简单的例子还算不上实战,应该做点实际的应用才算。做什么呢?现在手机不离手,我们就做个APP吧。详见新帖《一起来做APP.001》。
不知为何,没排序前,10竟然排到9前面。
我们如果希望按顺序,那就使用排序功能,order by 后面加上字段名,多个中间加逗号,排在前面的优先。
但是结果有点意外,9、10虽然规矩了,但居然跑到最前面。这是因为Z1为空,空值最小,所以数据库没有错,是我们没考虑周全。
我们如果希望按顺序,那就使用排序功能,order by 后面加上字段名,多个中间加逗号,排在前面的优先。
但是结果有点意外,9、10虽然规矩了,但居然跑到最前面。这是因为Z1为空,空值最小,所以数据库没有错,是我们没考虑周全。