当前位置:学学看123知识中心电脑教学数据库教程select - SQL的工作流程» 正文

select - SQL的工作流程

[06-11 18:16:40]   来源:http://www.xxk123.com  数据库教程   阅读:8985

导读:第一节 select - SQL的工作流程再复杂的SQL命令,也是由一些基本的结构组成的。所以在看、去做一条很复杂的SQL命令时,要会把它一级一级的折分,最后折成最简单的,这样才容易理解。而这个折分过程,如果不熟悉SQL命令的工作流程,那就比较难折分了。大体来说,它是先根据联接条件(即联接条件on中的表达式),把几个的表合成一个临时表,然后根据where中的条件进行过滤,过滤出来的结果根据分组条件再把这个临时表分成一组一组,然后对分别对些组进行字段计算,最后又得出一个临时表,然后又根据having中的条件对这个临时表进行再次过滤,最后输入到指定的地方,如数组、表等。它中间生成的临时表对用户来说,是完全透明的,用户是不可能使用、也不能创建,它是由系统自己创建、自己使用、自己撤除,完全不受用户控制的。我举个例子:有二个表:提货单thd、提货单明细thdmx:thd提货单号提货日期thdbhthrq012000/01/02022000/01/15032000/02/01thdmx提货单号产品编号提货数量thdbhcpbhThsl0100150100315010051202

select - SQL的工作流程,标签:sql数据库教程,access数据库教程,http://www.xxk123.com

第一节 select - SQL的工作流程

再复杂的SQL命令,也是由一些基本的结构组成的。所以在看、去做一条很复杂的SQL命令时,要会把它一级一级的折分,最后折成最简单的,这样才容易理解。而这个折分过程,如果不熟悉SQL命令的工作流程,那就比较难折分了。

大体来说,它是先根据联接条件(即联接条件on中的表达式),把几个的表合成一个临时表,然后根据where中的条件进行过滤,过滤出来的结果根据分组条件再把这个临时表分成一组一组,然后对分别对些组进行字段计算,最后又得出一个临时表,然后又根据having中的条件对这个临时表进行再次过滤,最后输入到指定的地方,如数组、表等。它中间生成的临时表对用户来说,是完全透明的,用户是不可能使用、也不能创建,它是由系统自己创建、自己使用、自己撤除,完全不受用户控制的。我举个例子:有二个表:提货单thd、提货单明细thdmx:

thd
提货单号提货日期thdbhthrq012000/01/02022000/01/15032000/02/01

thdmx

提货单号产品编号提货数量thdbhcpbhThsl010015010031501005120200113020021402005200300214

现在有个要求:要统计day1=2000/01/01至day2=2000/01/20这段时间内,提货数量大于10的产品有那些,它们各自的总提货量是多少。命令如下:

sele cpbh,sum(thsl) ;  from thd join thdmx ;    on thd.thdbh=thdmx.thdbh.and.thsl>10.and.betw(thrq,day1,day2) ;  grou by cpbh ;  into curs temp1

为什么把thsl>0和betw(thrq,day1,day2)这二个条件表达式放在on那里,参见on、where与having的区别。它的工作流程:

首先根据on中的过滤条件,对所涉及的表进行预处理。过程如下:

两个表根据thd.thdbh=thdmx.thdbh进行合并,变成一个这样的临时表:

thdbh1thrqthdbh2Cpbhthsl012000/01/02010015012000/01/020100315012000/01/020100512012000/01/020200113012000/01/020200214012000/01/020200520012000/01/020300214022000/01/15010015022000/01/150100315022000/01/150100512022000/01/150200113022000/01/150200214022000/01/150200520022000/01/150300214032000/02/01010015032000/02/010100315032000/02/010100512032000/02/010200113032000/02/010200214032000/02/010200520032000/02/010300214

合并是按照笛卡尔积进行计算的,即二个表都有10个记录,那积就会有10*10=100个记录,这是很历害的。但因为on条件中有过滤条件,所以VFP并不会这么笨,它会把符合这个条件的记录才放到临时表中的。这样,结果就少了很多记录了。结果出来后,再根据on后来的过滤条件thsl>10.and.betw(thrq,day1,day2)进行过滤,这样thsl大于10而且提货日期是在day1至day2的记录最后才出现在这一步的临时表中。

012000/01/020100315012000/01/020100512022000/01/150200113022000/01/150200214022000/01/150200520

现在轮到分组了。根据产品编号进行分组,它具体的分组方法我不知道是怎样,我想可能是这样的:

象在投票选举时点票那样,在上面那个临时表从头到尾扫一次,每经过一记录时,它就看一下,当前的产品编号是不是一个新的组,如果是就新增一个分组记号,相当于新增加一个被选举人,然后在它下面加上thsl的值,全部记录数完了,就看看有多少个分组标记,各个分组又有多少thsl。结果就是以下的样子:

00113002140031500532

这就是这条命令的结果了。然后把它生成一个cursor表,命令就完成了。如果再深入一点,把要求改成某段时间内全部产品的提货情况,如果没有进货记录,那就是0,一样要出现在结果表里。

这时,就涉及到三个表了:产品表cpb、提货表thd、提货明细表thdmx。我们先用内联接来把这三个表联接起来。

sele cpb.cpbh,cpb.cpmc,sum(iif(isnull(thdmx.thsl),0,thdmx.thsl)) as thsl ;  from cpbh join thdmx ;            join thd ;    on cpbh.cpbh=thdmx.cpbh ;    on thdmx.thdbh=thd.thdbh.and.betw(thd.thrq,day1,day2) ;  grou by cpbh ;  into curs temp1 

根据内联接的定义,即某个产品编号在产品表和提货明细表中都存在的记录,才会出现在结果表中,如果某种产品没有提货,那在提货明细表就没有这个记录,这样,也就不会出现在结果表中。那样就符合要求中的"全部产品"这个条件了。所以我们要把 产品表 左联接 提货明细表,这样不管这种产品有没有提货,它都会出现在结果表中,只是以null的值出现。但这个现象可以消除的。

[1] [2]  下一页


Tag:数据库教程sql数据库教程,access数据库教程电脑教学 - 数据库教程

Copyright 学学看123 All Right Reserved.

1 2 3 4 5 6 7 8 9 10