SQL 语句的解析过程

四、 HAVING子句

 

HAVING子句用来过滤前一步生成的临时表,并且只作用于分组后的数据,满足HAVING条件的GROUP被添加到虚拟表VT4中。

当应用了这个过滤:

 

HAVING COUNT(O.orderid) < 3

 

之后,生成的VT4表内容如下:

 

Groups
C.customerid

C.customerid

C.city

O.orderid

O.customerid

FISSA

FISSA

Madrid

NULL

NULL

FRNDO

FRNDO

Madrid

1

FRNDO

 

FRNDO

Madrid

2

FRNDO

 

需要注意的一点是,这里面使用的是COUNT(O.orderid),而不是COUNT(*),由于这个查询中添加了外部列,COUNT方法会忽略NULL的列,导致出现了你不想要的结果。

 

五、 SELECT 子句

 

尽管出现在sql语句的最前面,SELECT在第五步的时候才被处理,SELECT子句返回的表会最终返回给调用者。这个子句包含三个子阶段:(5-1)计算表达式,(5-2) 处理DISTINCT(5-3)应用TOP过滤。

 

1 计算表达式

 

SELECT子句中的表达式可以返回或者操作前一步表中返回的基本列。如果这个sql语句是一个聚合查询,在Step 3之后,你只能使用GROUP BY中的列,对不属于GROUP集合中的列必须使用聚合运算。不属于FROM表中基本列的必须为其起一个别名,如YEAR(orderdate) AS orderyear

 

注意:在SELECT子句中创建的别名,不能在之前的Step中使用,即使在SELECT子句中也不能。原因是sql的很多操作是同时操作(all at once operation),至于什么是all-at-once operation这里就不再介绍了。因此,SELECT子句中创建的别名只能在后面的子句中使用,如ORDER BY。例如:SELECT YEAR(orderdate) AS orderyear . . . ORDER BY orderyear

 

在这个例子中:

 

SELECT C.customerid, COUNT(O.orderid) AS numorders

 

结果会得到一个虚拟表VT5-1

 

C.customerid

numorders

FIFSSA

0

FRNDO

2

 

2、应用DISTINCT子句

 

如果sql语句中使用了DISTINCTsql会把重复列去掉,生成虚拟表VT5-2

 

3、应用TOP选项

 

TOP选项是T-SQL提供的一个功能,用来表示显示多少行。基于ORDER BY子句定义的顺序,指定个数的列会被查询出来。这个过程生成虚拟表VT5-3

 

正如上文提到的,这一步依赖于ORDER BY定义的顺序来决定哪些列应该显示在前面。如果你没有指定结果的ORDER BY顺序,也没有使用WITH TIES子句,每一次的返回结果可能会不一致。

 

在我们的例子中,Step 5-3被省略了,因为我们没有使用TOP关键字。

 

六、ORDER BY子句

 

前一步返回的虚拟表在这一步被排序,根据ORDER BY子句指定的顺序,返回游标VC6ORDER BY子句也是唯一一个可以使用SELECT子句创建的别名的地方。

 

注意:这一步和之前不同的地方在于,这一步返回的结果是一个游标,而不是表。sql是基于集合理论的,一个集合没有对他的行定义顺序,它只是一个成员的逻辑集合,因此成员的顺序并不重要。带有ORDER BY子句的sql返回一个按照特定序列组织每一行的对象。ANSI 把这样的一个对象叫游标。理解这一点对你了解sql很重要。


 

上面的步骤如图所示:

 

本教程由尚硅谷教育大数据研究院出品,如需转载请注明来源。

 

猜你喜欢

转载自blog.csdn.net/sggtgfs/article/details/84956559