日期:2014-05-16  浏览次数:20496 次

group by、order by、where、distinct使用方法小结

一. group by
1.GROUP BY子句主要用于对WHERE中得到的结果进行分组,也就是说它是在WHERE子句之后执行,对经过WHERE筛选后的结果按照某些列进行分组,之后进行相应的处理工作。

注意:如果在返回集字段中,这些字段要么就要包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中。

eg: select agent_Code,count(domain_name) from service_domain group by agent_code

说明:统计代理商注册域名的个数

2.Group By All [expressions]
如果使用 ALL 关键字,那么查询结果将包括由 GROUP BY 子句产生的所有组,即使某些组没有符合搜索条件的行。没有 ALL 关键字,包含 GROUP BY 子句的 SELECT 语句将不显示没有符合条件的行的组。

eg: select agent_Code,count(domain_name) from service_domain where agent_code != 'agent8175' group by all agent_code

说明:统计所有代理商注册域名的个数,如果没有all,则统计除agent8175之外的代理的注册域名的个数。

3.GROUP BY [Expressions] WITH CUBE | ROLLUP

首先需要说明的是Group By All 语句是不能和CUBE 和 ROLLUP 关键字一起使用的。

cube指定在结果集内不仅包含由 GROUP BY 提供的正常行,还包含汇总行。在结果集内返回每个可能的组和子组组合的 GROUP BY 汇总行。GROUP BY 汇总行在结果中显示为 NULL,但可用来表示所有值。使用 GROUPING 函数确定结果集内的空值是否是 GROUP BY 汇总值。   结果集内的汇总行数取决于 GROUP BY 子句内包含的列数。GROUP BY 子句中的每个操作数(列)绑定在分组 NULL 下,并且分组适用于所有其它操作数(列)。由于 CUBE 返回每个可能的组和子组组合,因此不论指定分组列时所使用的是什么顺序,行数都相同。

这个定义可以这样理解:如果是GROUP BY CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP BY操作(即GROUP BY(0))。即:CUBE操作字,除完成ROLLUP的功能外,再对ROLLUP后的结果集从右到左再聚合,逐个减少字段。CUBE常用于需要产生交叉报表的地方。

eg: select agent_Code,product_code,count(domain_name) from service_domain group by  cube(agent_code ,product_code )

ROLLUP部分ROLLUP:你也可以使用Rollup包含有限的几个小计,其语法是:Group by A,Rollup(B,C)。这种情况下,group by 条款先计算rollup中的部分,然后加上非rollup的部分,故层次为(A,B,C)(A,B)(A)。这里去除A不看就是GROUP BY(B,C),GROUP BY(B),GROUP BY(0),刚好就是ROLLUP(B,C)部分,然后再加上A,就得到GROUP BY A,ROLLUP(B,C)。

eg: select agent_Code,product_code,count(domain_name) from service_domain group by  rollup(agent_code ,product_code )

4.GROUPING SETS扩展
也就是通过它,你就可以控制GROUP BY后面的内容。举个例子来说,如果GROUP BY A,GROUPING SETS(B,C),那么实际上就想当于GROUP BY A,B UNION ALL GROUP BY A,C。

eg: select a,b,c,d,e,sum(c) sc from t group by a,grouping sets((b,c),(d,e));

5.having条件:
eg: select agent_Code,product_code,count(domain_name) from service_domain group by  agent_code ,product_code  having count(domain_name) > 4

二. distinct关键字 用于去重:
1.删除重复的数据DISTINCT 关键字可从 SELECT 语句的结果中除去重复的行。如果没有指定 DISTINCT,那么将返回所有行,包括重复的行。
eg:select distinct(domain_name),apply_date from service_domaindel

注意:distinct必须放在开头。

select * ,count(distinct domain_name) from service_domaindel group by domain_name 这个在mysql中支持,但是在oracle中不支持。


三. Group By 和 Having, Where ,Order by语句的执行顺序:
最后要说明一下的Group By, Having, Where, Order by几个语句的执行顺序。一个SQL语句往往会产生多个临时视图,那么这些关键字的执行顺序就非常重要了,因为你必须了解这个关键字是在对应视图形成前的字段进行操作还是对形成的临时视图进行操作,这个问题在使用了别名的视图尤其重要。以上列举的关键字是按照如下顺序进行执行的:Where, Group By, Having, Order by。首先where将最原始记录中不满足条件的记录删除(所以应该在where语句中尽量的将不符合条件的记录筛选掉,这样可以减少分组的次数),然后通过Group By关键字后面指定的分组条件将筛选得到的视图进行分组,接着系统根据Having关键字后面指定的筛选条件,将分组视图后不满足条件的记录筛选掉,然后按照Order By语句对视图进行排序,这样最终的结果就产生了。在这四个关键字中,只有在Order By语句中才可以使用最终视图的列名,如:   SELECT FruitName, ProductPlace, Price, ID AS IDE, Discount   FROM T_TEST_FRUITINFO   WHERE (ProductPlace = N'china')   ORDER BY IDE   这里只有在ORDER BY语句中才可以使用IDE,其他条件语句中如果需要引用列名则只能使用ID,而不能使用IDE。