SQL 语句的解析过程
三、 GROUP BY子句
这个子句会把前一步中生成的临时表中的数据进行分组,每一行都会分到并且只分到一个组里,生成虚拟表VT3。VT3表中包含了VT2表中所有的数据,和分组标识符。
这是生成的临时表VT3的内容如下:
Groups |
C.customerid |
C.city |
O.orderid |
O.customerid |
FISSA |
FISSA |
Madrid |
NULL |
NULL |
FRNDO |
FRNDO |
Madrid |
1 |
FRNDO |
FRNDO |
Madrid |
2 |
FRNDO |
|
|
KRLOS |
Madrid |
3 |
KRLOS |
KRLOS |
KRLOS |
Madrid |
4 |
KRLOS |
|
KRLOS |
Madrid |
5 |
KRLOS |
sql最终返回的结果中,每一个分组必须只能返回一行(除非被过滤掉),因此当一个sql语句中使用了GROUP BY时,在GROUP BY后面处理的子句,如SELECT,HAVING子句等,只能使用出现在GROUP BY后面的列,对于没有出现GROUP BY后面的列必须使用聚合函数(如 MAX ,MIN,COUNT,AVG等),保证每一个GROUP只返回一行。
四、 HAVING子句
HAVING子句用来过滤前一步生成的临时表,并且只作用于分组后的数据,满足HAVING条件的GROUP被添加到虚拟表VT4中。
当应用了这个过滤:
HAVING COUNT(O.orderid) < 3
之后,生成的VT4表内容如下:
Groups |
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的列,导致出现了你不想要的结果。
本教程由尚硅谷教育大数据研究院出品,如需转载请注明来源,欢迎大家关注尚硅谷公众号(atguigu)了解更多。