你真的懂T-sql吗?

 你真的懂T-sql 语句的逻辑执行顺序吗?

先创建示例数据库

 

创建两个表 Class和Choose表, 

class: 

choose: 

 大家可能很容易看懂以下代码

 

目的是找出所有班级中学生人数少于3的班级和班级人数,

查出的结果

 

那它们的执行顺序和过程是怎么样的?分析一下

1.执行from语句中的两个表 ,执行笛卡尔乘积(交叉连接)

会得到虚拟表 VT1 ,表中会出现28条数据(4*7)。

2. on 筛选器(联接条件)

  sql中的筛选器有三种(on,where,having),on 筛选器被应用到上步生成的虚拟表 VT1中的所有行。只有在 联接条件为 TRUE(满足ON条件)的时候才会包含在由步骤2产生的虚拟表VT2中,在此示例中  a.classname=b.classname,由此可以从虚拟表VT1中28条数据中筛选出6条数据

 

对于NULL值,在筛选器中(on,where,having)中,比较两个NULL值,结果为UNKNOWN(三值逻辑之一),会当做FALSE处理,然而在排序操作和分组操作等等,会认为NULL和NULL是相等的。

3.添加外部行

执行left outer join , 两表联接,如果left outer join,则左边为保留表,如果right outer join ,则右边为保留表,如果full outer join ,则两边都为保留表。

此步骤会返回VT2中的所有行以及保留表中在步骤2中过滤掉的行(外部行),外部行中非保留表中的列值赋为NULL,最后生成虚拟表VT3。

 

 假如还有一张联表Student,那么就要重复1,2,3步了。

4.where 筛选器

选取 辅导员是 Michael 的行,返回虚拟表VT4。(此处未排序,不可用聚合筛选器)

5. 分组

 返回虚拟表VT5,表中包括两个部分,Groups 和 Raw,即实际组构成的成组部分和由上一步返回的行组成的原始部分。

 

返回虚拟表VT5 

这时候,因为不是筛选器,所以NULL与NULL认为是相等的。 

六:CUBE或ROLLUP选项。 

此示例没有,如有返回虚拟表 VT6 

七:having 筛选器

  

筛选掉包含3名学生的班级,返回虚拟表VT7

八:处理select列表

 

返回虚拟表VT8 .

在select列表中创建的别名不能在前面的步骤中使用,而且不能在用于select表达式的其他表达式,受SQL的独有的特性--同时操作。

即:select a1+1 as b1,b1+1 as b2,这样是不支持的,因为它们是同时的,与逻辑顺序无关,在csharp交换值要用到临时变量,而T-sql不需要,直接update dbo.test set c1=c2,c2=c1 ,如此就交换了值,此操作是同时的,瞬间的。

select中创建的列的别名可以再order by中调用。 

九:distinct子句

此示例没有,如果有则返回VT9。 

十:order by子句

order by 认为两个NULL值相等,在T-sql中NULL排位比已知值低。

返回的是游标VC10 .并不是一个表。

会出现错误 

 

 十一:TOP

返回指定的行数或百分数。 


令附一逻辑趣味题:

假设你被诊断得了一种怪病。医生给你开了两种药--A和B。每个瓶子装三个药片,两种药片的大小、形状、味道、颜色都一样。瓶子上有药的名称,一个瓶子盛A,另一个盛B,但药片本身没有任何标记。医生吩咐你每天吃一片A和一片B,共三天。正确服用,治愈你的病,否则,死亡。

第一天,你服了一片A和一片B,第二天,你发现有人动了你的药,瓶子B空了,瓶子A里有一个药片,餐桌上放着三个药片。你意识到药片已经混了。你打电话给药房得知今天没货。

你该怎样正确服药呢? 

 

 

posted @ 2009-11-03 21:30  zabery  阅读(2755)  评论(23编辑  收藏  举报