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 ...
随机推荐
-
设计模式之美:Adapter(适配器)
索引 别名 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):简单直接的对象适配器. 实现方式(二):实现双向类适配器. 别名 包装器(Wrapper) 意图 将一个类的接口转换成客户 ...
-
QQ拼音还是不行哇
QQ拼音还是不行啊,虽说没广告,但是很多词条没有,例如知乎.蒋京虎. 泰囧……
-
基本输入输出系统BIOS---键盘输入
基本输入输出系统BIOS概述 硬盘操作系统DOS建立在BIOS的基础上,通过BIOS操纵硬件,例如DOS调用BIOS显示I/O程序完成输入显示,调用打印I/O完成打印输出 通常应用程序应该调用DOS提 ...
-
(转载)Excel文档保存的时候,提示“文档未保存”
亲测,成功搞定 Excel文档保存的时候,提示“文档未保存”? 先打开你需要处理的excel,然后打开工具栏--宏--录制新宏--确定--停止录制宏--宏-宏--编辑--复制以下程序Sub 恢复保存( ...
-
cogs 线型网络(状压dp)
/* 需要好大的空间..... 而且lowbit理解的不是很好 先放到博客里 以后慢慢研究 */ #include<iostream> #include<cstdio> #in ...
-
基于Python,scrapy,redis的分布式爬虫实现框架
原文 http://www.xgezhang.com/python_scrapy_redis_crawler.html 爬虫技术,无论是在学术领域,还是在工程领域,都扮演者非常重要的角色.相比于其他 ...
-
Luogu 1006 传纸条 / NOIP 2008 传纸条(动态规划)
Luogu 1006 传纸条 / NOIP 2008 传纸条(动态规划) Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m ...
-
原生JS实现百度搜索功能
今天呢给大家分享一下自己用原生JS做的一个百度搜索功能,下面上代码: <!DOCTYPE html> <html> <head> <meta charset= ...
-
计蒜客 X的平方根(二分法)
设计函数int sqrt(int x),计算 xx 的平方根. 输入格式 输入一个 整数 xx,输出它的平方根.直到碰到文件结束符(EOF)为止. 输出格式 对于每组输入,输出一行一个整数,表示输入整 ...
-
Linux内核分析 笔记二 操作系统是如何工作的 ——by王玥
一.知识要点 1.计算机是如何工作的?(总结)——三个法宝 存储程序计算机工作模型,计算机系统最最基础性的逻辑结构: 函数调用堆栈,高级语言得以运行的基础,只有机器语言和汇编语言的时候堆栈机制对于计算 ...