基础知识普及

此处不会涉及到文绉绉的知识,但还是强调一下基础的重要性,即使你理解了所有的概念,但当组合起来用时也会一头雾水。

逻辑查询处理阶段


判断sql返回的数据有没有某个字段java代码_外连接


在以上的10个处理步骤中,每一步的处理都生成一个虚拟表来作为下一步的输入。虚拟表对于调用者或输出查询来说是不存在的,仅在最后步骤生成的表才会返回给调用者或者输出查询。如果某一子句没有出现在SQL语句中, 这一步就被简单跳过。

这10个具体步骤是:

1.FROM: from子句中的两个表首先进行交叉连接(笛卡尔积), 生成虚拟表VT1。

2.ON: on条件作用在VT1上, 将条件为True的行生成VT2。

3.OUTER: 如果outer join被指定, 则根据外连接条件, 将左表or右表or多表的未出现在VT2查询结果中的行加入到VT2后生成VT3。

4.WHERE: VT3表中应用Where条件, 结果为真的行用来生成VT4。

5.GROUP BY: 根据Group by指定的列, 将VT4的行组织到不同的组中, 生成VT5。

6.CLUB|ROLLUP: 超级组(分组之后的分组)被添加到VT5中, 生成VT6。

7.HAVING: Having用来筛选组, VT6上符合条件的组,将用来生成VT7。

8.SELECT: select子句用来选择指定的列, 并生成VT8。

9.DISTINCT: 从VT8中删除重复的行后, VT9被生成。

10.ORDER BY: 根据Order by子句, VT9中的行被排序, 生成游标10。

注意事项:

  • 第一步中FROM: :

需要对两表同时存在的列添加前缀, 以免混淆.

  • 第二步中ON:

在SQL特有的三值逻辑(true,false,unknown)中, unkown的值也是确定的,只是在不同情况下有时为true, 有时为false。一个总的原则是: unknown的值非真即假,非假即真。也就是说,unknown只能取true和false里面的一个值, 但是unknown的相反还是unknown。如:

在ON、WHERE和HAVING中做过滤条件时, unknown看做false;

在CHECK约束中, unknown被看做是true;

在条件中, 两个NULL的比较结果还是Unknown;

在UNIQUE和PRIMARY KEY约束、排序和分组中, NULL被看做是相等的. 。例如:Group by 将null分为一组, 而order by将所有null排在一起.

  • 第三步中OUTER:

如果多余两张表, 则将VT3和FROM中的下一张表再次执行从第一步到第三步的过程.

  • 第四步中WHERE:

由于此刻没有分组, 也没有执行select,所以 where子句中不能写分组函数, ,也不能使用表的别名, 并且, 只有在外连接时, on和where的逻辑才是不同的,因此建议把连接条件放在on中。

  • 第五步中GROUP BY:

如果查询中包含Group by 子句, 那么所有的后续操作(having, select等)都是对每一组的结果进行操作.

Group by子句中可以使用组函数, 在Sql 2000中一旦使用组函数,其后面的步骤将都不能处理,而在Sql2005中没有这个限制。

  • 第六步不常用,略过
  • 第七步中HAVING:

having表达式是仅有的分组条件。注意:count(*)不会忽略掉null,而count(field)会;此外分组函数中不支持子查询做输入.。

  • 第八步中SELECT:

如果包含Group By子句,那么在第5步后将只能使用Group By子句中出现的列,如果要使用其他原始列,则只能使用组函数。

另外, select在第八步才执行,因此别名只能第八步之后才能使用, ,并且只能在order by中使用。

  • 第九步中DISTINCT::

当使用Group By子句时, 使用Distinct是多余的, 他不会删除任何记录.

  • 第十步中ORDER BY:

按Order by子句指定的列排序后,返回游标VC10。别名只能在Order by子句中使用。

如果定义了Distinct子句, 则只能排序上一步中返回的表VT9,如果没有指定Distinct子句,则可以排序不再最终结果集中的列。例如:如果不加Distinct,则Order by可以访问VT7和VT8中的内容。

这一步最不同的是它返回的是游标而不是表,Sql是基于集合论的,集合中的元素是没有顺序的,一个在表上引用Order by排序的查询返回一个按照特定物理顺序组织的对象——游标。所以对于视图、子查询、派生表等均不能将order by结果作为其数据来源。

建议:使用表的表达式时, 不允许使用order by子句的查询,除非你真的要对行排序, 否则不要使用order by 子句.