Sql Server的艺术(三) SQL聚合函数的应用
SQL提供的聚合函数有求和,最大值,最小值,平均值,计数函数等。
聚合函数及其功能:
函数名称 | 函数功能 |
SUM() | 返回选取结果集中所有值的总和 |
MAX() | 返回选取结果集中所有值的最大值 |
MIN() | 返回选取结果集中所有值的最小值 |
AVG() | 返回选取结果集中所有值的平均值 |
COUNT() | 返回选取结果集中行的数目 |
学习本节所需要的两张表:
CREATE TABLE TEACHER
(
ID INT IDENTITY (,) PRIMARY KEY , --主键,自增长
TNO INT NOT NULL, --教工号
TNAME CHAR() NOT NULL, --教师姓名
CNO INT NOT NULL, --课程号
SAL INT, --工资
DNAME CHAR() NOT NULL, --所在系
TSEX CHAR() NOT NULL, --性别
AGE INT NOT NULL --年龄
)
INSERT INTO dbo.TEACHER VALUES( ,'王军',,,'数学','男',)
INSERT INTO dbo.TEACHER VALUES( ,'李彤',,,'生物','女',)
INSERT INTO dbo.TEACHER VALUES( ,'王永军',,,'计算机','女',)
INSERT INTO dbo.TEACHER VALUES( ,'刘晓婧',,,'计算机','女',)
INSERT INTO dbo.TEACHER VALUES( ,'高维',,,'电子工程','男',)
INSERT INTO dbo.TEACHER VALUES( ,'李伟',,,'机械工程','女',)
INSERT INTO dbo.TEACHER VALUES( ,'刘辉',,,'生物','女',)
INSERT INTO dbo.TEACHER VALUES( ,'刘伟',,,'计算机','男',)
INSERT INTO dbo.TEACHER VALUES( ,'刘静',,,'经济管理','男',)
INSERT INTO dbo.TEACHER VALUES( ,'刘奕锴',,,'计算机','女',)
INSERT INTO dbo.TEACHER VALUES( ,'高维',,,'经济管理','男',) CREATE TABLE COURSE
(
ID INT IDENTITY (,) PRIMARY KEY , --主键,自增长
CNO INT NOT NULL, --课程号
CNAME CHAR() NOT NULL, --课程名称
CTIME INT NOT NULL, --学时
SCOUNT INT NOT NULL, --容纳人数
CTEST SMALLDATETIME NOT NULL, --考试时间
)
INSERT INTO dbo.COURSE VALUES( ,'应用数学基础',,,'2006-7-10')
INSERT INTO dbo.COURSE VALUES( ,'生物工程概论',,,'2006-7-8')
INSERT INTO dbo.COURSE VALUES( ,'计算机软件基础',,,'2006-7-8')
INSERT INTO dbo.COURSE VALUES( ,'计算机硬件基础',,,'2006-6-28')
INSERT INTO dbo.COURSE VALUES( ,'模拟电路设计',,,'2006-7-10')
INSERT INTO dbo.COURSE VALUES( ,'机械设计实践',,,'2006-7-14')
INSERT INTO dbo.COURSE VALUES( ,'生物化学',,,'2006-7-2')
INSERT INTO dbo.COURSE VALUES( ,'数据库设计',,,'2006-7-1')
INSERT INTO dbo.COURSE VALUES( ,'设计理论',,,'2006-6-30')
INSERT INTO dbo.COURSE VALUES( ,'计算机入门',,,'2006-6-29')
INSERT INTO dbo.COURSE VALUES( ,'数字电路设计基础',,,'2006-6-20')
INSERT INTO dbo.COURSE VALUES( ,'数字电路设计基础%',,,'2006-6-20')
INSERT INTO dbo.COURSE VALUES( ,'_设计理论',,,'2006-6-30')
数据表
一、求和函数——SUM()
--求所有老师的工资总和
SELECT SUM(SAL) AS TOTAL_SAL FROM dbo.TEACHER
注意:
SUM()函数只能作用于数值类型数据。
对某列求和,如果存在NULL值,则SUM函数会忽略该值。
二、计数函数——COUNT()
--使用COUNT(),对表的总行数
SELECT COUNT(*) AS TOTAL FROM dbo.TEACHER --使用COUNT(),对表列的数据计数
--SAL列有一行数据为空,所以结果与其他两列不同
SELECT COUNT(TNAME) AS TOTAL,COUNT(SAL) AS TOTAL,COUNT(DNAME) AS TOTAL FROM dbo.TEACHER --使用COUNT(),对表的列的数据一起包含查询,需要用到CAST,以及"+"连接符
--ZongLie 是包含SAL和TNAME两列的数据,放在一起查询的
SELECT COUNT(TNAME) AS Total_Name,COUNT(SAL) AS Total_Sal,COUNT(DNAME) AS Total_Name,COUNT(CAST(SAL AS VARCHAR())+TNAME) AS ZongLie FROM dbo.TEACHER --使用COUNT(),满足where条件的查询
SELECT COUNT(*) AS TOTAL FROM dbo.TEACHER WHERE TSEX='男'
注意一下两点:
COUNT(*),计算表中行的总数,即使表中行的数据为null,也被计入在内。
COUNT(column),计算column列包含行的数目,如果该列中某行数据为null,则该行不计入总数。
三、最大/最小值函数——MAX()/MIN()
--MAX()的使用,查询工资最高/最低
SELECT MAX(SAL) AS 最高工资,MIN(SAL) AS 最低工资 FROM dbo.TEACHER
--以下是两种错误的写法,聚合函数的处理是数据组,他将teacher看作是一个组,而TNAME,SAL的数据没有进行分组,所以select语句没有逻辑意义。
--该列没有包含在聚合函数或 GROUP BY 子句中。
SELECT TNAME,MAX(SAL) FROM dbo.TEACHER
--聚合不应出现在 WHERE 子句中,除非该聚合位于 HAVING 子句或选择列表所包含的子查询中,并且要对其进行聚合的列是外部引用。
SELECT * FROM dbo.TEACHER WHERE AGE=MAX(AGE)
--那么接下来演示正确子句使用MAX/MIN查询
--子句中要写完整的select查询语句
SELECT TNO,TNAME,SAL,DNAME,AGE FROM dbo.TEACHER WHERE AGE=(SELECT MAX(AGE) FROM dbo.TEACHER) --显示年龄最大老师的信息
--MAX()/MIN()不仅可以用作于数值类型数据,也可以用作于字符串或者日期类型
--字符串类型是根据字母A~Z排序的:
SELECT MAX(TNAME) FROM dbo.TEACHER --结果:王永军 开头字母:W --MAX()/MIN()用于时间类型
SELECT MAX(CTEST) AS 近,MIN(CTEST) AS 远 FROM dbo.COURSE
注意:
确认列中的最大值/最小值时,MAX,MIN函数会忽略NULL值。但是,如果该列所有行的值都是NULL,则函数返回NULL。
四、均值函数--AVG()
--均值函数是用来计算列的数据平均值的,跟SUM()一样,只能用来计算数值类型
SELECT AVG(SAL) AS 平均工资 FROM dbo.TEACHER --计算工资的平均值
--利用COUNT() SUM() AVG()来看下求平均值的过程
SELECT AVG(SAL) AS AVG函数算的平均工资,COUNT(*) AS 总人数,SUM(SAL)/COUNT(TNAME) AS 总的工资除总的人数 FROM dbo.TEACHER
--运行结果发现,AVG算的平均工资跟手动算的不一样,因为AVG算平均工资的时候忽略了“NULL”,所排除了一个人数,
--而我们平常不管有没有工资,都要把这个人算上在求平均,所以导致结果不一样,网上也有有不同说法,可自行斟酌,仅代表个人想法
SELECT SUM(SAL) AS 工资总和 FROM dbo.TEACHER --162730 162730/12=13560
SELECT COUNT(SAL) AS 工资列的总行数排除NULL FROM dbo.TEACHER --11 162730/11=14793 工资有一个为空,忽略
SELECT COUNT(TNAME) AS 人数列的总行数排除NULL FROM dbo.TEACHER --12
SELECT COUNT(*) AS 表的总行数 FROM dbo.TEACHER --12
SELECT * FROM dbo.TEACHER --表数据
--带where子句使用条件限制平均值
SELECT AVG(SAL) FROM dbo.TEACHER WHERE DNAME='电子工程' --这个结果同上
SELECT * FROM dbo.TEACHER WHERE DNAME='电子工程'
--聚合分析的重值处理
SELECT COUNT(ALL SAL) AS 所有的 FROM dbo.TEACHER
SELECT COUNT(DISTINCT SAL) AS 除去重复的 FROM dbo.TEACHER
SELECT * FROM dbo.TEACHER --表数据
--使用ALL后,计算出所有行数,使用distinct后,排除了重复的数值
--除了"COUNT(*)"函数外,其他函数在计算的过程中都忽略了NULL,排除NULL进行分析计算
--聚合函数也可以组合使用,即在一条select语句中,可以使用多个聚合函数
SELECT COUNT(*) AS 行数,MIN(AGE) AS 最小年龄,MAX(SAL) AS 最高工资,AVG(AGE) AS 平均年龄,SUM(SAL)/COUNT(*) AS 平均工资 FROM dbo.TEACHER
五、组合查询GROUP BY,HAVING
--GROUP BY子句分组查询
SELECT TSEX+'教师' AS 老师,AVG(SAL) AS 平均工资 FROM dbo.TEACHER GROUP BY TSEX --男 女老师的平均工资
--来分析一下DBMS执行实例的步骤
--首先执行FROM子句,将表TEACHER作为中间表
--如果有WHERE子句,DBMS则根据其中的搜索条件,从中间表中去除那些值为False的列.这里没有WHERE子句,所以DBMS跳过了这个步骤
--根据GROUP BY子句制定的分组列即TSEX,DBMS将中间表中的数据进行分组。这里TSEX的值为‘男’,另一组中TSEX值为‘女’
--DBNS为每个行组计算SELECT子句中的值,并为每组生成查询结果中的一行。对于TSEX值为‘男’的行组,SELECT子句首先执行‘TSEX+教师’,得到‘男教师’列值,再执行‘AVG(SAL)’,求得该行组中的SAL的均值,将这两个值作为结果表中的一条记录;同样,对TESX值为‘女’的行组,进行类似的操作得到另一条记录
--GROUP BY子句根据多列组合行
SELECT DNAME,TSEX,COUNT(*) AS 人数 FROM dbo.TEACHER GROUP BY DNAME,TSEX --查询各系男女老师的人数
--会发现有的没有男或女,因为没有值,系统默认为NULL,不显示了
--GROUP BY子句中的NULL处理
SELECT SAL AS 工资,COUNT(*) AS 数量 FROM dbo.TEACHER GROUP BY SAL
--HAVING子句
--GROUP BY子句会根据所选的列进行分组,但实际上,我们往往还需要删除那些不满足条件的行组,为了实现这个功能SQL提供了HAVING子句。
--通常GROUP BY与HAVING使用
SELECT DNAME AS 系,COUNT(*) AS 数量 FROM dbo.TEACHER GROUP BY DNAME HAVING COUNT(*)>= --选择系的数量大于等2
--如果指定了GROUP BY子句,那么HAVING子句定义的搜索条件将作用于这个GROUP BY子句创建的那些组
--如果指定的WHERE子句而没有指定GROUP BY子句,那么HAVING子句定义的搜索条件将作用于WHERE子句的输出,并把这个输出看作是一个组
--如果既没有指定GROUP BY子句也没有指定WHERE子句,那么HAVING子句定义的搜索条件将作用于FROM子句的输出并把这个输出看作一个组
SELECT * FROM dbo.TEACHER --HAVING与where子句不同的作用
SELECT DNAME AS 系,COUNT(TSEX) AS 数量 FROM dbo.TEACHER WHERE TSEX='女' GROUP BY DNAME --女老师的系拥有女老师的数量
--不能把单个的TSEX的值应用于组,包括HAVING子句中的列必须是组列。因此,在这种情况下,WHERE子句就不可能用HAVING子句代替
--在数据的分组聚合分析中,HAVING子句与WHERE子句也可以共存。WHERE子句在分组之前过滤,而HAVING子句则过滤分组后的数据 SELECT DNAME AS 系,COUNT(TSEX) AS 数量 FROM dbo.TEACHER WHERE TSEX='女' GROUP BY DNAME HAVING COUNT(TSEX)>= --女老师的系拥有至少2个女老师的数量
--通常情况下,HANVING子句都与GROUP BY子句一起使用,这样就可以聚合相关数据,然后筛选这些数据,以进一步细化搜索。但如果没有GROUP BY子句,HAVING子句也可以单独使用。
--HAVING子句的单独使用
SELECT COUNT(TSEX) FROM dbo.TEACHER WHERE TSEX='女' HAVING COUNT(TSEX)> --数量大于3的女老师
注意:
GROUP BY子句依据column列里的数据对行进行分组,即具有相同值得行被划为一组。它一般与聚合函数同时使用。当然,这里的SUM函数也可以是其他聚合函数。
所有的组合列(GROUP BY子句中列出的列)必须来自于FROM子句列出的表,不能根据实际值、聚合函数结果或者其他表达式计算的值来对行分组。
来总结一下SELECT语句查询子句:
SELECT语句查询子句及其所有子句
顺序号 | 子句关键词 | 子句功能 |
1 | SELECT | 从指定表中取出指定列的数据 |
2 | FROM | 制定要查询操作的表 |
3 | WHERE | 用来规定一种选择查询的标准 |
4 | GROUP BY | 对结果集进行分组,常与聚合函数一起使用 |
5 | HAVING | 返回选取的结果集中行的数目 |
6 | ORDER BY | 指定分组的搜寻条件 |
如果在同一个SELECT语句中用到上表的一下查询子句,则各查询顺序排列由低到高的顺序。因此,完整的SELECT查询语句可以如下:
--SELECT select_list
--FROM table_source
--[WHERE search_condition]
--[GROUP BY group_by_expression]
--[HAVING search_condition]
--[ORDER BY order_expression [ASC \ DESC]]
--[]是可选项
--至少有两名女教师的系拥有的女教师数量,并且按数量排序
SELECT DNAME AS 系名,COUNT(TSEX) AS 数量
FROM dbo.TEACHER
WHERE TSEX='女'
GROUP BY DNAME
HAVING COUNT(TSEX)>=
ORDER BY 数量
Sql Server的艺术(三) SQL聚合函数的应用的更多相关文章
- SQL语句汇总(三)——聚合函数、分组、子查询及组合查询
拖了一个星期,终于开始写第三篇了.走起! 聚合函数: SQL中提供的聚合函数可以用来统计.求和.求最值等等. 分类: –COUNT:统计行数量 –SUM:获取单个列的合计值 –AVG:计算某个列的平均 ...
- SQL Server数据库————模糊查询和聚合函数
***********模糊查询*********/ 关键字: like (!!!!字符串类型) in (,,) 匹配()内的某个具体值(括号里可以写多个值) between... and.. 在某两 ...
- 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)
从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://w ...
- (转) 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)
原文地址: http://www.cnblogs.com/lyhabc/p/4682986.html 这一篇是从0开始搭建SQL Server AlwaysOn 的第三篇,这一篇才真正开始搭建Alwa ...
- SQL Server 中截取字符串常用的函数
SQL Server 中截取字符串常用的函数: 1.LEFT ( character_expression , integer_expression ) 函数说明:LEFT ( '源字符串' , '要 ...
- SQL Server中的三种Join方式
1.测试数据准备 参考:Sql Server中的表访问方式Table Scan, Index Scan, Index Seek 这篇博客中的实验数据准备.这两篇博客使用了相同的实验数据. 2.SQ ...
- SQL Server中的LEFT、RIGHT函数
SQL Server中的LEFT.RIGHT函数. LEFT:返回字符串中从左边开始指定个数字符. LEFT(character_expression,integer_expression); RIG ...
- (转载) 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)
这一篇是从0开始搭建SQL Server AlwaysOn 的第三篇,这一篇才真正开始搭建AlwaysOn,前两篇是为搭建AlwaysOn 做准备的 步骤 这一篇依然使用step by step的方式 ...
- SQL Server基础知识三十三问 (1-7)
1. SQL Server运行在什么端口上? 可以被修改么? 答: 1433端口. 可以修改的, 在SQL Server Configuration Manager的SQL Server Networ ...
- 使用CASE表达式替代SQL Server中的动态SQL
原文:使用CASE表达式替代SQL Server中的动态SQL 翻译自: http://www.mssqltips.com/sqlservertip/1455/using-the-case-expre ...
随机推荐
- oracle分页,带有排序字段
select detail_num,carriage_num,ed_date,created_date from (select rownum id,detail_num,carriage_num,e ...
- java_web学习(六) request对象中的get和post差异
1.get与post的区别 Get和Post方法都是对服务器的请求方式,只是他们传输表单的方式不一样. 下面我们就以传输一个表单的数据为例,来分析get与Post的区别 1.1 get方法 jsp中 ...
- 【请您听我说】PHP语法特点的一些看法
一.基本认识 PHP是干什么的?百度百科上提到说:PHP就是一门脚本语言,开发用的,相信这个你们只要去搜一下,就会有一大堆关于PHP概念的解释. 相信我们对PHP的初步认识是从浏览器开始的吧,当我们每 ...
- bzoj:2423: [HAOI2010]最长公共子序列
Description 字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0, ...
- [51nod1673]树有几多愁
lyk有一棵树,它想给这棵树重标号. 重标号后,这棵树的所有叶子节点的值为它到根的路径上的编号最小的点的编号. 这棵树的烦恼值为所有叶子节点的值的乘积. lyk想让这棵树的烦恼值最大,你只需输出最大烦 ...
- 最小生成树—prim算法
最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...
- Wolf and Rabbit
http://acm.hdu.edu.cn/showproblem.php?pid=1222 Wolf and Rabbit Time Limit: 2000/1000 MS (Java/Others ...
- JAVA经典算法面试40题及答案
现在是3月份,也是每年开年企业公司招聘的高峰期,同时有许多的朋友也出来找工作.现在的招聘他们有时会给你出一套面试题或者智力测试题,也有的直接让你上机操作,写一段程序.算法的计算不乏出现,基于这个原因我 ...
- Mysql开启远程连接方法
分类: 数据库开发技术 解决MySQL不允许从远程访问的方法 开启 MySQL 的远程登陆帐号有两大步: 1.确定服务器上的防火墙没有阻止 3306 端口. MySQL 默认的端口是 3306 ,需要 ...
- LAMP和LNMP,你更愿意选择谁,为什么?
https://www.zhihu.com/question/19697826 http://www.simongong.net lamp 的全称是linux + apache + mysql +ph ...