笔记237 SqlServer 中 Group by、having、order by、Distinct 使用注意事项 COUNT函数 COUNT_BIG函数

笔记237 SqlServer 中 Group by、having、order by、Distinct 使用注意事项  COUNT函数  COUNT_BIG函数 

 1 --SqlServer 中 Group by、having、order by、Distinct 使用注意事项 2013-4-14
 2 
 3 
 4 SELECT COUNT(*) AS COUNT,REQUEST,METHOD FROM REQUESTMETH GROUP BY
 5 REQUEST,METHOD HAVING (REQUEST ='FC.OCEAN.JOB.SERVER.CBIZOZBKHEADER' OR REQUEST='FC.Ocean.Job.Server.CBizOzDocHeader')
 6 AND COUNT(*) >3
 7 ORDER BY REQUEST
 8 
 9 
10 --注意事项:--------------------------------------------------------------------
11 --
12 --HAVING后的条件不能用别名COUNT>3 必须使用COUNT(*) >3,否则报:列名 'COUNT' 无效。
13 --
14 --having 子句中的每一个元素并不一定要出现在select列表中  having只是group by之后再筛选
15 --但是Group by 子句中的每一个元素都要出现在select列表中
16 
17 
18 --如果把该语句写成:
19 
20 SELECT COUNT(*) AS COUNT,REQUEST,METHOD FROM REQUESTMETH GROUP BY
21 REQUEST ORDER BY REQUEST
22 
23 --那么将报:
24 --
25 --选择列表中的列 'REQUESTMETH.method' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。
26 
27 
28 --注意:
29 --1、使用GROUP BY 子句时,SELECT 列表中的非汇总列必须为GROUP BY 列表中的项。
30 --(即select 中的字段必须为GROUP BY 列表中的项,如果select 中有字段的话)
31 --例如
32 SELECT COUNT(*) AS COUNT FROM [dbo].[CT_Append] GROUP BY [I_A_CardType] ORDER BY [I_A_CardType]
33 --2、分组时,所有的NULL值分为一组。
34 --3、GROUP BY 列表中一般不允许出现复杂的表达试、显示标题以及SELECT列表中的位置标号。
35 --
36 --
37 SELECT REQUEST,METHOD, COUNT(*) AS COUNT FROM REQUESTMETH GROUP BY
38 REQUEST,2 ORDER BY REQUEST 
39 
40 --错误信息为:每个 GROUP BY 表达式都必须包含至少一个列引用。
41 
42 
43 --GROUP BY 中使用 ORDER BY注意事项:---------------------------------------------
44 
45 SELECT COUNT(*) AS COUNT FROM REQUESTMETH GROUP BY REQUEST,METHOD ORDER BY REQUEST,METHOD
46 
47 --这样是允许的, ORDER BY后面的字段包含在GROUP BY 子句中,order by字段没有在group by子句中也就是group by临时表没有order by指定的字段所以会报错
48 
49 SELECT COUNT(*) AS COUNTS FROM REQUESTMETH GROUP BY REQUEST ORDER BY COUNT(*) DESC
50 
51 --这样是允许的,ORDER BY后面的字段包含在聚合函数中,结果集同下面语句一样
52 
53 SELECT COUNT(*) AS COUNTS FROM REQUESTMETH GROUP BY REQUEST ORDER BY COUNTS DESC
54 
55 --这样是允许的,区别于HAVING,HAVING后不允许跟聚合函数的别名作为过滤条件
56 
57 
58 SELECT COUNT(*) AS COUNTS FROM REQUESTMETH GROUP BY REQUEST ORDER BY METHOD
59 
60 --这样是错误的:ORDER BY 子句中的列 "REQUESTMETH.method" 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。
61 --既没有在select 中也没有在group by中
62 
63 --SELECT DISTINCT 中使用 ORDER BY注意事项:-----------------------------------
64 
65 SELECT DISTINCT BOOKID FROM BOOK ORDER BY BOOKNAME
66 
67 --以上语句将报:
68 
69 --如果指定了SELECT DISTINCT,那么ORDER BY 子句中的项就必须出现在选择列表中。
70 
71 --因为以上语句类似
72 
73 SELECT BOOKID FROM BOOK GROUP BY BOOKID ORDER BY BOOKNAME
74 
75 --其实错误信息也为:
76 
77 --ORDER BY子句中的列"BOOK.BookName" 无效,因为该列没有包含在聚合函数或GROUP BY 子句中。
78 
79 
80 --应该改为:
81 
82 SELECT DISTINCT BOOKID,BOOKNAME FROM BOOK ORDER BY BOOKNAME
83 SELECT DISTINCT BOOKID,BOOKNAME FROM BOOK
84 SELECT BOOKID,BOOKNAME FROM BOOK GROUP BY BOOKID,BOOKNAME
85 
86 --以上两句查询结果是一致的,DISTINCT的语句其实完全可以等效的转换为GROUP BY语句

 

https://time.geekbang.org/column/article/82865
distinct 和 group by 的性能

如果表 t 的字段 a 上没有索引,那么下面这两条语句的性能是不是相同的?
select a from t group by a
select distinct a from t;


首先需要说明的是,这种 group by 的写法,并不是 SQL 标准的写法。
标准的 group by 语句,是需要在 select 部分加一个聚合函数,比如:
select a,count(*) from t group by a

这条语句的逻辑是:按照字段 a 分组,计算每组的 a 出现的次数。在这个结果里,由于做的是聚合计算,相同的 a 只出现一次。
没有了 count(*) 以后,也就是不再需要执行“计算总数”的逻辑时,第一条语句的逻辑就变成是:
按照字段 a 做分组,相同的 a 的值只返回一行,而这就是 distinct 的语义,
所以不需要执行聚合函数时,distinct 和 group by 这两条语句的语义和执行流程是相同的,因此执行性能也相同。


这两条语句的执行流程是下面这样的。
1.创建一个临时表,临时表有一个字段 a,并且在这个字段 a 上创建一个唯一索引;
2.遍历表 t,依次取数据插入临时表中:如果发现唯一键冲突,就跳过;否则插入成功;
3.遍历完成后,将临时表作为结果集返回给客户端



COUNT (Transact-SQL)
返回组中的项数。COUNT 与 COUNT_BIG 函数类似。两个函数唯一的差别是它们的返回值。COUNT 始终返回 int 数据类型值。COUNT_BIG 始终返回 bigint 数据类型值。后面可以跟 OVER 子句。

COUNT ( { [ [ ALL | DISTINCT ] expression ] | * } )

参数
ALL
对所有的值进行聚合函数运算。ALL 是默认值。
DISTINCT
指定 COUNT 返回唯一非空值的数量。
expression
除 text、image 或 ntext 以外任何类型的表达式。不允许使用聚合函数和子查询。
*
指定应该计算所有行以返回表中行的总数。COUNT(*) 不需要任何参数,而且不能与 DISTINCT 一起使用。COUNT(*) 不需要 expression 参数,因为根据定义,该函数不使用有关任何特定列的信息。COUNT(*) 返回指定表中行数而不删除副本。它对各行分别计数。包括包含空值的行。


返回类型
int

备注
COUNT(*) 返回组中的项数。包括 NULL 值和重复项。
COUNT(ALL expression) 对组中的每一行都计算 expression 并返回非空值的数量。
COUNT(DISTINCT expression) 对组中的每一行都计算 expression 并返回唯一非空值的数量。
对于大于 2^31-1 的返回值,COUNT 生成一个错误。这时应使用 COUNT_BIG。

 

 

 


COUNT_BIG (Transact-SQL)
返回组中的项数。COUNT_BIG 的用法与 COUNT 函数类似。两个函数唯一的差别是它们的返回值。COUNT_BIG 始终返回 bigint 数据类型值。COUNT 始终返回 int 数据类型值。后面可能跟随 OVER 子句。

COUNT_BIG ( { [ ALL | DISTINCT ] expression } | * )

参数
ALL
对所有的值进行聚合函数运算。ALL 是默认值。
DISTINCT
指定 COUNT_BIG 返回唯一非空值的数量。
expression
是任何类型的表达式。不允许使用聚合函数和子查询。
*
指定应该计算所有行以返回表中行的总数。COUNT_BIG(*) 不需要任何参数,而且不能与 DISTINCT 一起使用。COUNT(*) 不需要 expression 参数,因为根据定义,该函数不使用有关任何特定列的信息。COUNT_BIG(*) 返回指定表中的行数并将重复行计算在内。它对各行分别计数。包括包含空值的行。

返回类型
bigint


备注
COUNT_BIG(*) 返回组中的项数。包括 NULL 值和重复项。
COUNT_BIG(ALL expression) 对组中的每一行都计算 expression 并返回非空值的数量。
COUNT_BIG(DISTINCT expression) 对组中的每一行都计算 expression 并返回唯一非空值的数量。

 

 

 

f

posted @ 2013-08-04 19:49  桦仔  阅读(986)  评论(0编辑  收藏  举报