
数据准确性的口号有哪些
精确, 准确团结, 团结。
越战越勇,勇往直前。
耶自己看看还行不, 你这个题材有点少。
数据准确性的标语
国法庄严。
国法尊严。
祖训:失之毫厘;而谬以千里。
今昔:质量百分百。
社会每人抬。
国歌国际歌国法庄严
数据少得到的结论不准确,可以怎么表达
数据库设计方法、规范与技巧 一、数据库设计过程 数据库技术是信息资源管理最有效的手段。
数据库设计是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,有效存储数据,满足用户信息要求和处理要求。
数据库设计中需求分析阶段综合各个用户的应用需求(现实世界的需求),在概念设计阶段形成独立于机器特点、独立于各个DBMS产品的概念模式(信息世界模型),用E-R图来描述。
在逻辑设计阶段将E-R图转换成具体的数据库产品支持的数据模型如关系模型,形成数据库逻辑模式。
然后根据用户处理的要求,安全性的考虑,在基本表的基础上再建立必要的视图(VIEW)形成数据的外模式。
在物理设计阶段根据DBMS特点和处理的需要,进行物理存储安排,设计索引,形成数据库内模式。
1. 需求分析阶段 需求收集和分析,结果得到数据字典描述的数据需求(和数据流图描述的处理需求)。
需求分析的重点是调查、收集与分析用户在数据管理中的信息要求、处理要求、安全性与完整性要求。
需求分析的方法:调查组织机构情况、调查各部门的业务活动情况、协助用户明确对新系统的各种要求、确定新系统的边界。
常用的调查方法有: 跟班作业、开调查会、请专人介绍、询问、设计调查表请用户填写、查阅记录。
分析和表达用户需求的方法主要包括自顶向下和自底向上两类方法。
自顶向下的结构化分析方法(Structured Analysis,简称SA方法)从最上层的系统组织机构入手,采用逐层分解的方式分析系统,并把每一层用数据流图和数据字典描述。
数据流图表达了数据和处理过程的关系。
系统中的数据则借助数据字典(Data Dictionary,简称DD)来描述。
数据字典是各类数据描述的集合,它是关于数据库中数据的描述,即元数据,而不是数据本身。
数据字典通常包括数据项、数据结构、数据流、数据存储和处理过程五个部分(至少应该包含每个字段的数据类型和在每个表内的主外键)。
数据项描述={数据项名,数据项含义说明,别名,数据类型,长度, 取值范围,取值含义,与其他数据项的逻辑关系} 数据结构描述={数据结构名,含义说明,组成:{数据项或数据结构}} 数据流描述={数据流名,说明,数据流来源,数据流去向, 组成:{数据结构},平均流量,高峰期流量} 数据存储描述={数据存储名,说明,编号,流入的数据流,流出的数据流, 组成:{数据结构},数据量,存取方式} 处理过程描述={处理过程名,说明,输入:{数据流},输出:{数据流}, 处理:{简要说明}} 2. 概念结构设计阶段 通过对用户需求进行综合、归纳与抽象,形成一个独立于具体DBMS的概念模型,可以用E-R图表示。
概念模型用于信息世界的建模。
概念模型不依赖于某一个DBMS支持的数据模型。
概念模型可以转换为计算机上某一DBMS支持的特定数据模型。
概念模型特点: (1) 具有较强的语义表达能力,能够方便、直接地表达应用中的各种语义知识。
(2) 应该简单、清晰、易于用户理解,是用户与数据库设计人员之间进行交流的语言。
概念模型设计的一种常用方法为IDEF1X方法,它就是把实体-联系方法应用到语义数据模型中的一种语义模型化技术,用于建立系统信息模型。
使用IDEF1X方法创建E-R模型的步骤如下所示: 2.1 第零步——初始化工程 这个阶段的任务是从目的描述和范围描述开始,确定建模目标,开发建模计划,组织建模队伍,收集源材料,制定约束和规范。
收集源材料是这阶段的重点。
通过调查和观察结果,业务流程,原有系统的输入输出,各种报表,收集原始数据,形成了基本数据资料表。
2.2 第一步——定义实体 实体集成员都有一个共同的特征和属性集,可以从收集的源材料——基本数据资料表中直接或间接标识出大部分实体。
根据源材料名字表中表示物的术语以及具有“代码”结尾的术语,如客户代码、代理商代码、产品代码等将其名词部分代表的实体标识出来,从而初步找出潜在的实体,形成初步实体表。
2.3 第二步——定义联系 IDEF1X模型中只允许二元联系,n元联系必须定义为n个二元联系。
根据实际的业务需求和规则,使用实体联系矩阵来标识实体间的二元关系,然后根据实际情况确定出连接关系的势、关系名和说明,确定关系类型,是标识关系、非标识关系(强制的或可选的)还是非确定关系、分类关系。
如果子实体的每个实例都需要通过和父实体的关系来标识,则为标识关系,否则为非标识关系。
非标识关系中,如果每个子实体的实例都与而且只与一个父实体关联,则为强制的,否则为非强制的。
如果父实体与子实体代表的是同一现实对象,那么它们为分类关系。
2.4 第三步——定义码 通过引入交叉实体除去上一阶段产生的非确定关系,然后从非交叉实体和独立实体开始标识侯选码属性,以便唯一识别每个实体的实例,再从侯选码中确定主码。
为了确定主码和关系的有效性,通过非空规则和非多值规则来保证,即一个实体实例的一个属性不能是空值,也不能在同一个时刻有一个以上的值。
找出误认的确定关系,将实体进一步分解,最后构造出IDEF1X模型的键基视图(KB图)。
2.5 第四步——定义属性 从源数据表中抽取说明性的名词开发出属性表,确定属性的所有者。
定义非主码属性,检查属性的非空及非多值规则。
此外,还要检查完全依赖函数规则和非传递依赖规则,保证一个非主码属性必须依赖于主码、整个主码、仅仅是主码。
以此得到了至少符合关系理论第三范式的改进的IDEF1X模型的全属性视图。
2.6 第五步——定义其他对象和规则 定义属性的数据类型、长度、精度、非空、缺省值、约束规则等。
定义触发器、存储过程、视图、角色、同义词、序列等对象信息。
3. 逻辑结构设计阶段 将概念结构转换为某个DBMS所支持的数据模型(例如关系模型),并对其进行优化。
设计逻辑结构应该选择最适于描述与表达相应概念结构的数据模型,然后选择最合适的DBMS。
将E-R图转换为关系模型实际上就是要将实体、实体的属性和实体之间的联系转化为关系模式,这种转换一般遵循如下原则: 1)一个实体型转换为一个关系模式。
实体的属性就是关系的属性。
实体的码就是关系的码。
2)一个m:n联系转换为一个关系模式。
与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性。
而关系的码为各实体码的组合。
3)一个1:n联系可以转换为一个独立的关系模式,也可以与n端对应的关系模式合并。
如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为n端实体的码。
4)一个1:1联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。
5)三个或三个以上实体间的一个多元联系转换为一个关系模式。
与该多元联系相连的各实体的码以及联系本身的属性均转换为关系的属性。
而关系的码为各实体码的组合。
6)同一实体集的实体间的联系,即自联系,也可按上述1:1、1:n和m:n三种情况分别处理。
7)具有相同码的关系模式可合并。
为了进一步提高数据库应用系统的性能,通常以规范化理论为指导,还应该适当地修改、调整数据模型的结构,这就是数据模型的优化。
确定数据依赖。
消除冗余的联系。
确定各关系模式分别属于第几范式。
确定是否要对它们进行合并或分解。
一般来说将关系分解为3NF的标准,即: 表内的每一个值都只能被表达一次。
表内的每一行都应该被唯一的标识(有唯一键)。
表内不应该存储依赖于其他键的非键信息。
4. 数据库物理设计阶段 为逻辑数据模型选取一个最适合应用环境的物理结构(包括存储结构和存取方法)。
根据DBMS特点和处理的需要,进行物理存储安排,设计索引,形成数据库内模式。
5. 数据库实施阶段 运用DBMS提供的数据语言(例如SQL)及其宿主语言(例如C),根据逻辑设计和物理设计的结果建立数据库,编制与调试应用程序,组织数据入库,并进行试运行。
数据库实施主要包括以下工作:用DDL定义数据库结构、组织数据入库 、编制与调试应用程序、数据库试运行 6. 数据库运行和维护阶段 数据库应用系统经过试运行后即可投入正式运行。
在数据库系统运行过程中必须不断地对其进行评价、调整与修改。
包括:数据库的转储和恢复、数据库的安全性、完整性控制、数据库性能的监督、分析和改进、数据库的重组织和重构造。
建模工具的使用 为加快数据库设计速度,目前有很多数据库辅助工具(CASE工具),如Rational公司的Rational Rose,CA公司的Erwin和Bpwin,Sybase公司的PowerDesigner以及Oracle公司的Oracle Designer等。
ERwin主要用来建立数据库的概念模型和物理模型。
它能用图形化的方式,描述出实体、联系及实体的属性。
ERwin支持IDEF1X方法。
通过使用ERwin建模工具自动生成、更改和分析IDEF1X模型,不仅能得到优秀的业务功能和数据需求模型,而且可以实现从IDEF1X模型到数据库物理设计的转变。
ERwin工具绘制的模型对应于逻辑模型和物理模型两种。
在逻辑模型中,IDEF1X工具箱可以方便地用图形化的方式构建和绘制实体联系及实体的属性。
在物理模型中,ERwin可以定义对应的表、列,并可针对各种数据库管理系统自动转换为适当的类型。
设计人员可根据需要选用相应的数据库设计建模工具。
例如需求分析完成之后,设计人员可以使用Erwin画ER图,将ER图转换为关系数据模型,生成数据库结构;画数据流图,生成应用程序。
二、数据库设计技巧 1. 设计数据库之前(需求分析阶段) 1) 理解客户需求,询问用户如何看待未来需求变化。
让客户解释其需求,而且随着开发的继续,还要经常询问客户保证其需求仍然在开发的目的之中。
2) 了解企业业务可以在以后的开发阶段节约大量的时间。
3) 重视输入输出。
在定义数据库表和字段需求(输入)时,首先应检查现有的或者已经设计出的报表、查询和视图(输出)以决定为了支持这些输出哪些是必要的表和字段。
举例:假如客户需要一个报表按照邮政编码排序、分段和求和,你要保证其中包括了单独的邮政编码字段而不要把邮政编码糅进地址字段里。
4) 创建数据字典和ER 图表 ER 图表和数据字典可以让任何了解数据库的人都明确如何从数据库中获得数据。
ER图对表明表之间关系很有用,而数据字典则说明了每个字段的用途以及任何可能存在的别名。
对SQL 表达式的文档化来说这是完全必要的。
5) 定义标准的对象命名规范 数据库各种对象的命名必须规范。
2. 表和字段的设计(数据库逻辑设计) 表设计原则 1) 标准化和规范化 数据的标准化有助于消除数据库中的数据冗余。
标准化有好几种形式,但Third Normal Form(3NF)通常被认为在性能、扩展性和数据完整性方面达到了最好平衡。
简单来说,遵守3NF 标准的数据库的表设计原则是:“One Fact in One Place”即某个表只包括其本身基本的属性,当不是它们本身所具有的属性时需进行分解。
表之间的关系通过外键相连接。
它具有以下特点:有一组表专门存放通过键连接起来的关联数据。
举例:某个存放客户及其有关定单的3NF 数据库就可能有两个表:Customer 和Order。
Order 表不包含定单关联客户的任何信息,但表内会存放一个键值,该键指向Customer 表里包含该客户信息的那一行。
事实上,为了效率的缘故,对表不进行标准化有时也是必要的。
2) 数据驱动 采用数据驱动而非硬编码的方式,许多策略变更和维护都会方便得多,大大增强系统的灵活性和扩展性。
举例,假如用户界面要访问外部数据源(文件、XML 文档、其他数据库等),不妨把相应的连接和路径信息存储在用户界面支持表里。
还有,如果用户界面执行工作流之类的任务(发送邮件、打印信笺、修改记录状态等),那么产生工作流的数据也可以存放在数据库里。
角色权限管理也可以通过数据驱动来完成。
事实上,如果过程是数据驱动的,你就可以把相当大的责任推给用户,由用户来维护自己的工作流过程。
3) 考虑各种变化 在设计数据库的时候考虑到哪些数据字段将来可能会发生变更。
举例,姓氏就是如此(注意是西方人的姓氏,比如女性结婚后从夫姓等)。
所以,在建立系统存储客户信息时,在单独的一个数据表里存储姓氏字段,而且还附加起始日和终止日等字段,这样就可以跟踪这一数据条目的变化。
字段设计原则 4) 每个表中都应该添加的3 个有用的字段 dRecordCreationDate,在VB 下默认是Now(),而在SQL Server 下默认为GETDATE() sRecordCreator,在SQL Server 下默认为NOT NULL DEFAULT USER nRecordVersion,记录的版本标记;有助于准确说明记录中出现null 数据或者丢失数据的原因 5) 对地址和电话采用多个字段 描述街道地址就短短一行记录是不够的。
Address_Line1、Address_Line2 和Address_Line3 可以提供更大的灵活性。
还有,电话号码和邮件地址最好拥有自己的数据表,其间具有自身的类型和标记类别。
6) 使用角色实体定义属于某类别的列 在需要对属于特定类别或者具有特定角色的事物做定义时,可以用角色实体来创建特定的时间关联关系,从而可以实现自我文档化。
举例:用PERSON 实体和PERSON_TYPE 实体来描述人员。
比方说,当John Smith, Engineer 提升为John Smith, Director 乃至最后爬到John Smith, CIO 的高位,而所有你要做的不过是改变两个表PERSON 和PERSON_TYPE 之间关系的键值,同时增加一个日期\\\/时间字段来知道变化是何时发生的。
这样,你的PERSON_TYPE 表就包含了所有PERSON 的可能类型,比如Associate、Engineer、Director、CIO 或者CEO 等。
还有个替代办法就是改变PERSON 记录来反映新头衔的变化,不过这样一来在时间上无法跟踪个人所处位置的具体时间。
7) 选择数字类型和文本类型尽量充足 在SQL 中使用smallint 和tinyint 类型要特别小心。
比如,假如想看看月销售总额,总额字段类型是smallint,那么,如果总额超过了$32,767 就不能进行计算操作了。
而ID 类型的文本字段,比如客户ID 或定单号等等都应该设置得比一般想象更大。
假设客户ID 为10 位数长。
那你应该把数据库表字段的长度设为12 或者13 个字符长。
但这额外占据的空间却无需将来重构整个数据库就可以实现数据库规模的增长了。
8) 增加删除标记字段 在表中包含一个“删除标记”字段,这样就可以把行标记为删除。
在关系数据库里不要单独删除某一行;最好采用清除数据程序而且要仔细维护索引整体性。
3. 选择键和索引(数据库逻辑设计) 键选择原则: 1) 键设计4 原则 为关联字段创建外键。
所有的键都必须唯一。
避免使用复合键。
外键总是关联唯一的键字段。
2) 使用系统生成的主键 设计数据库的时候采用系统生成的键作为主键,那么实际控制了数据库的索引完整性。
这样,数据库和非人工机制就有效地控制了对存储数据中每一行的访问。
采用系统生成键作为主键还有一个优点:当拥有一致的键结构时,找到逻辑缺陷很容易。
3) 不要用用户的键(不让主键具有可更新性) 在确定采用什么字段作为表的键的时候,可一定要小心用户将要编辑的字段。
通常的情况下不要选择用户可编辑的字段作为键。
4) 可选键有时可做主键 把可选键进一步用做主键,可以拥有建立强大索引的能力。
索引使用原则: 索引是从数据库中获取数据的最高效方式之一。
95%的数据库性能问题都可以采用索引技术得到解决。
1) 逻辑主键使用唯一的成组索引,对系统键(作为存储过程)采用唯一的非成组索引,对任何外键列采用非成组索引。
考虑数据库的空间有多大,表如何进行访问,还有这些访问是否主要用作读写。
2) 大多数数据库都索引自动创建的主键字段,但是可别忘了索引外键,它们也是经常使用的键,比如运行查询显示主表和所有关联表的某条记录就用得上。
3) 不要索引memo\\\/note 字段,不要索引大型字段(有很多字符),这样作会让索引占用太多的存储空间。
4) 不要索引常用的小型表 不要为小型数据表设置任何键,假如它们经常有插入和删除操作就更别这样作了。
对这些插入和删除操作的索引维护可能比扫描表空间消耗更多的时间。
4. 数据完整性设计(数据库逻辑设计) 1) 完整性实现机制: 实体完整性:主键 参照完整性: 父表中删除数据:级联删除;受限删除;置空值 父表中插入数据:受限插入;递归插入 父表中更新数据:级联更新;受限更新;置空值 DBMS对参照完整性可以有两种方法实现:外键实现机制(约束规则)和触发器实现机制 用户定义完整性: NOT NULL;CHECK;触发器 2) 用约束而非商务规则强制数据完整性 采用数据库系统实现数据的完整性。
这不但包括通过标准化实现的完整性而且还包括数据的功能性。
在写数据的时候还可以增加触发器来保证数据的正确性。
不要依赖于商务层保证数据完整性;它不能保证表之间(外键)的完整性所以不能强加于其他完整性规则之上。
3) 强制指示完整性 在有害数据进入数据库之前将其剔除。
激活数据库系统的指示完整性特性。
这样可以保持数据的清洁而能迫使开发人员投入更多的时间处理错误条件。
4) 使用查找控制数据完整性 控制数据完整性的最佳方式就是限制用户的选择。
只要有可能都应该提供给用户一个清晰的价值列表供其选择。
这样将减少键入代码的错误和误解同时提供数据的一致性。
某些公共数据特别适合查找:国家代码、状态代码等。
5) 采用视图 为了在数据库和应用程序代码之间提供另一层抽象,可以为应用程序建立专门的视图而不必非要应用程序直接访问数据表。
这样做还等于在处理数据库变更时给你提供了更多的自由。
数据收集,整理和分析的方法有多种,其中这种检查表主要应用于
分析数据有两种,1 列表法将实验数据按一定规律用列表方式表达出来是记录和处理实验数据最常用的方法。
表格的设计要求对应关系清楚、简单明了、有利于发现相关量之间的物理关系;此外还要求在标题栏中注明物理量名称、符号、数量级和单位等;根据需要还可以列出除原始数据以外的计算栏目和统计栏目等。
最后还要求写明表格名称、主要测量仪器的型号、量程和准确度等级、有关环境条件参数如温度、湿度等。
2 作法作法可以最醒目地表达物理量间的变化关系。
从线上还可以简便求出实验需要的某些结果(如直线的斜率和截距值等),读出没有进行观测的对应点(内插法),或在一定条件下从线的延伸部分读到测量范围以外的对应点(外推法)。
此外,还可以把某些复杂的函数关系,通过一定的变换用直线表示出来。
例如半导体热敏电阻的电阻与温度关系为,取对数后得到,若用半对数坐标纸,以lgR为纵轴,以1/T为横轴画,则为一条直线。
关于数据库的描述,正确的是( )。
问
一下内容纯属抄袭~,希望有点用~8.2聚合函数的应用聚合函数在数据库数据的查询分析中,应用十分广泛。
本节将分别对各聚合函数的应用进行说明。
8.2.1求和函数——SUM()求和函数SUM()用于对数据求和,返回选取结果集中所有值的总和。
语法如下。
SELECTSUM(column_name)FROMtable_name说明:SUM()函数只能作用于数值型数据,即列column_name中的数据必须是数值型的。
实例1SUM函数的使用从TEACHER表中查询所有男教师的工资总数。
TEACHER表的结构和数据可参见5.2.1节的表5-1,下同。
实例代码:SELECTSUM(SAL)ASBOYSALFROMTEACHERWHERETSEX='男'运行结果如图8.1所示。
图8.1TEACHER表中所有男教师的工资总数实例2SUM函数对NULL值的处理从TEACHER表中查询年龄大于40岁的教师的工资总数。
实例代码:SELECTSUM(SAL)ASOLDSALFROMTEACHERWHEREAGE>=40运行结果如图8.2所示。
图8.2TEACHER表中所有年龄大于40岁的教师的工资总数当对某列数据进行求和时,如果该列存在NULL值,则SUM函数会忽略该值。
8.2.2计数函数——COUNT()COUNT()函数用来计算表中记录的个数或者列中值的个数,计算内容由SELECT语句指定。
使用COUNT函数时,必须指定一个列的名称或者使用星号,星号表示计算一个表中的所有记录。
两种使用形式如下。
*COUNT(*),计算表中行的总数,即使表中行的数据为NULL,也被计入在内。
*COUNT(column),计算column列包含的行的数目,如果该列中某行数据为NULL,则该行不计入统计总数。
1.使用COUNT(*)函数对表中的行数计数COUNT(*)函数将返回满足SELECT语句的WHERE子句中的搜索条件的函数。
实例3COUNT(*)函数的使用查询TEACHER表中的所有记录的行数。
实例代码:SELECTCOUNT(*)ASTOTALITEMFROMTEACHER运行结果如图8.3所示。
图8.3使用COUNT(*)函数对表中的行数计数在该例中,SELECT语句中没有WHERE子句,那么认为表中的所有行都满足SELECT语句,所以SELECT语句将返回表中所有行的计数,结果与5.2.1节的表5-1列出的TEACHER表的数据相吻合。
如果DBMS在其系统表中存储了表的行数,COUNT(*)将很快地返回表的行数,因为这时,DBMS不必从头到尾读取表,并对物理表中的行计数,而直接从系统表中提取行的计数。
而如果DBMS没有在系统表存储表的行数,将具有NOTNULL约束的列作为参数,使用COUNT()函数,则可能更快地对表行计数。
注意COUNT(*)函数将准确地返回表中的总行数,而仅当COUNT()函数的参数列没有NULL值时,才返回表中正确的行计数,所以仅当受NOTNULL限制的列作为参数时,才可使用COUNT()函数代替COUNT(*)函数。
2.使用COUNT()函数对一列中的数据计数COUNT()函数可用于对一列中的数据值计数。
与忽略了所有列的COUNT(*)函数不同,COUNT()函数逐一检查一列(或多列)中的值,并对那些值不是NULL的行计数。
实例4查询多列中所有记录的行数查询TEACHER表中的TNO列、TNAME列以及SAL列中包含的所有数据行数。
实例代码:SELECTCOUNT(TNO)ASTOTAL_TNO,COUNT(TNAME)ASTOTAL_TNAME,COUNT(SAL)ASTOTAL_SALFROMTEACHER运行结果如图8.4所示。
图8.4使用COUNT()函数对一列中的数据计数可见,TNO列与TNAME列由于其中不含有NULL值,所以其计数与使用COUNT(*)函数对TEACHER表中的记录计数结果相一致,而SAL列由于其中有两行数据为NULL,所以这两列没有被计入在内,计数结果也就是8。
3.使用COUNT()函数对多列中的数据计数COUNT()函数不仅可用于对一列中的数据值计数,也可以对多列中的数据值计数。
如果对多列计数,则需要将要计数的多列通过连接符连接后,作为COUNT()函数的参数。
下面将结合具体的多列计数的实例,说明其使用过程。
*说明关于如何使用连接符连接多列可参见本书的7.2节。
实例5使用COUNT()函数对多列中的数据计数统计TEACHER表中的TNO列、TNAME列和SAL列中分别包含的数据行数,以及TNO列和TNAME列、TNAME列和SAL列一起包含的数据行数。
实例代码:SELECTCOUNT(TNO)ASTOTAL_TNO,COUNT(TNAME)ASTOTAL_TNAME,COUNT(SAL)ASTOTAL_SAL,COUNT(CAST(TNOASVARCHAR(5))+TNAME)AST_NONAME,COUNT(TNAME+CAST(SALASVARCHAR(5)))AST_NAMESALFROMTEACHER运行结果如图8.5所示。
图8.5使用COUNT()函数对多列中的数据计数在进行两列的连接时,由于它们的数据类型不一致,因此要使用CAST表达式将它们转换成相同的数据类型。
在7.2.1节已经讲过,如果在被连接的列中的任何一列有NULL值时,那么连接的结果为NULL,则该列不会被COUNT()函数计数。
注意COUNT()函数只对那些传递到函数中的参数不是NULL的行计数。
4.使用COUNT函数对满足某种条件的记录计数也可以在SELECT语句中添加一些子句约束来指定返回记录的个数。
实例6使用COUNT函数对满足某种条件的记录计数查询TEACHER表中女教师记录的数目。
实例代码:SELECTCOUNT(*)ASTOTALWOMENFROMTEACHERWHERETSEX='女'运行结果如图8.6所示。
图8.6使用COUNT函数对满足某种条件的记录计数这时结果为6而不是前面的所有记录10。
之所以可以通过WHERE子句定义COUNT()函数的计数条件,这与SELECT语句各个子句的执行顺序是分不开的。
前面已经讲过,DBMS首先执行FROM子句,而后是WHERE子句,最后是SELECT子句。
所以COUNT()函数只能用于满足WHERE子句定义的查询条件的记录。
没有包括在WHERE子句的查询结果中的记录,都不符合COUNT()函数。
8.2.3最大\\\/最小值函数—MAX()\\\/MIN()当需要了解一列中的最大值时,可以使用MAX()函数;同样,当需要了解一列中的最小值时,可以使用MIN()函数。
语法如下。
SELECTMAX(column_name)\\\/MIN(column_name)FROMtable_name说明:列column_name中的数据可以是数值、字符串或是日期时间数据类型。
MAX()\\\/MIN()函数将返回与被传递的列同一数据类型的单一值。
实例7MAX()函数的使用查询TEACHER表中教师的最大年龄。
实例代码:SELECTMAX(AGE)ASMAXAGEFROMTEACHER运行结果如图8.7所示。
图8.7TEACHER表中教师的最大年龄然而,在实际应用中得到这个结果并不是特别有用,因为经常想要获得的信息是具有最大年龄的教师的教工号、姓名、性别等信息。
然而SQL不支持如下的SELECT语句。
SELECTTNAME,DNAME,TSEX,MAX(AGE)FROMTEACHER因为聚合函数处理的是数据组,在本例中,MAX函数将整个TEACHER表看成一组,而TNAME、DNAME和TSEX的数据都没有进行任何分组,因此SELECT语句没有逻辑意义。
同样的道理,下面的代码也是无效的。
SELECTTNAME,DNAME,TSEX,SAL,AGEFROMTEACHERWHEREAGE=MAX(AGE)解决这个问题的方法,就是在WHERE子句中使用子查询来返回最大值,然后再基于这个返回的最大值,查询相关信息。
实例8在WHERE子句中使用子查询返回最大值查询TEACHER表中年纪最大的教师的教工号、姓名、性别等信息。
实例代码:SELECTTNAME,DNAME,TSEX,SAL,AGEFROMTEACHERWHEREAGE=(SELECTMAX(AGE)FROMTEACHER)运行结果如图8.8所示。
图8.8在WHERE子句中使用子查询返回最大值MAX()和MIN()函数不仅可以作用于数值型数据,也可以作用于字符串或是日期时间数据类型的数据。
实例9MAX()函数用于字符型数据如下面代码:SELECTMAX(TNAME)ASMAXNAMEFROMTEACHER运行结果如图8.9所示。
图8.9在字符串数据类型中使用MAX的结果可见,对于字符串也可以求其最大值。
*说明对字符型数据的最大值,是按照首字母由A~Z的顺序排列,越往后,其值越大。
当然,对于汉字则是按照其全拼拼音排列的,若首字符相同,则比较下一个字符,以此类推。
当然,对与日期时间类型的数据也可以求其最大\\\/最小值,其大小排列就是日期时间的早晚,越早认为其值越小,如下面的实例。
实例10MAX()、MIN()函数用于时间型数据从COURSE表中查询最早和最晚考试课程的考试时间。
其中COURSE表的结构和数据可参见本书6.1节的表6-1。
实例代码:SELECTMIN(CTEST)ASEARLY_DATE,MAX(CTEST)ASLATE_DATEFROMCOURSE运行结果如图8.10所示。
图8.10COURSE表中最早和最晚考试课程的考试时间可见,返回结果的数据类型与该列定义的数据类型相同。
注意确定列中的最大值(最小值)时,MAX()(MIN())函数忽略NULL值。
但是,如果在该列中,所有行的值都是NULL,则MAX()\\\/MIN()函数将返回NULL值。
8.2.4均值函数——AVG()函数AVG()用于计算一列中数据值的平均值。
语法如下。
SELECTAVG(column_name)FROMtable_name说明:AVG()函数的执行过程实际上是将一列中的值加起来,再将其和除以非NULL值的数目。
所以,与SUM()函数一样,AVG()函数只能作用于数值型数据,即列column_name中的数据必须是数值型的。
实例11AVG()函数的应用从TEACHER表中查询所有教师的平均年龄。
实例代码:SELECTAVG(AGE)ASAVG_AGEFROMTEACHER运行结果如图8.11所示。
图8.11TEACHER表中所有教师的平均年龄在计算平均值时,AVG()函数将忽略NULL值。
因此,如果要计算平均值的列中有NULL值,计算均值时,要特别注意。
实例12AVG()函数对NULL值的处理从TEACHER表中查询所有教师的平均工资。
实例代码:SELECTAVG(SAL)ASAVG_AGE1,SUM(SAL)\\\/COUNT(*)ASAVG_AGE2,SUM(SAL)\\\/COUNT(SAL)ASAVG_AGE3FROMTEACHER运行结果如图8.12所示。
图8.12TEACHER表中所有教师的平均工资可以发现得到了不同的结果。
实际上,“AVG(SAL)”与“SUM(SAL)\\\/COUNT(SAL)”语句是等价的。
因为AVG(SAL)语句的执行过程实际上是将SAL列中的值加起来,再将其和(也就等价于SUM(SAL))除以非NULL值的数目(也就等价于COUNT(SAL))。
而语句“SUM(SAL)\\\/COUNT(*)”则不然,因为COUNT(*)返回的是表中所有记录的个数,而不管SAL列中的数值是否为NULL。
注意AVG()函数在计算一列的平均值时,忽略NULL值。
但是,如果在该列中,所有行的值都是NULL,则AVG()函数将返回NULL值。
如果不想对列中的所有值求平均,则可在WHERE子句中使用搜索条件来限制用于计算均值的行。
实例13在WHERE子句中使用搜索条件来限制用于计算均值的行从TEACHER表中查询所有计算机系教师的平均年龄。
实例代码:SELECTAVG(AGE)ASAVGCOMPUTER_AGEFROMTEACHERWHEREDNAME='计算机'运行结果如图8.13所示。
图8.13TEACHER表中所有计算机系教师的平均年龄当执行SELECT语句时,DBMS将表中的每行对WHERE子句中的搜索条件“DNAME='计算机'”求值。
只有那些搜索条件为True时,行中的AGE值才传到均值函数AVG(AGE)中。
当然,除了显示表中某列的平均值,还可用AVG()函数作为WHERE子句的一部分。
与前面介绍的MAX()函数一样,不能直接用于WHERE子句,必须以子查询的形式。
实例14AVG()函数作为WHERE子句中搜索条件的一部分从TEACHER表中查询所有年龄高于平均年龄的教师的信息。
实例代码:SELECT*FROMTEACHERWHEREAGE>=(SELECTAVG(AGE)FROMTEACHER)ORDERBYAGE运行结果如图8.14所示。
图8.14TEACHER表中所有年龄高于平均年龄的教师的信息8.2.5聚合分析的重值处理前面介绍的5种聚合函数,可以作用于所选列中的所有数据(不管列中的数据是否有重置),也可以只对列中的非重值进行处理,即把重复的值只取一次进行聚合分析。
当然,对于MAX()\\\/MIN()函数来讲,重值处理意义不大。
可以使用ALL关键字指明对所选列中的所有数据进行处理,使用DISTINCT关键字指明对所选列中的非重值数据进行处理。
以AVG()函数为例,语法如下。
SELECTAVG([ALL\\\/DISTINCT]column_name)FROMtable_name说明:[ALL\\\/DISTINCT]在缺省状态下,默认是ALL关键字,即不管是否有重值,处理所有数据。
其他聚合函数的用法与此相同。
注意MicrosoftAccess数据库不支持在聚合函数中使用DISTINCT关键字。
实例15聚合分析的重值处理从TEACHER表中查询工资SAL列中存在的所有记录数。
实例代码:SELECTCOUNT(ALLSAL)ASALLSAL_COUNTFROMTEACHER运行结果如图8.15所示。
图8.15TEACHER表中工资SAL列中存在的所有记录数当然,在代码中去除ALL关键字,也可以得到相同的结果。
而如果从TEACHER表中,查询工资SAL列中存在的不同记录的数目,可采用如下代码。
SELECTCOUNT(DISTINCTSAL)ASDISTINCTSAL_COUNTFROMTEACHER运行结果如图8.16所示。
图8.16TEACHER表中SAL列存在的不同记录的数目对比两个结果,使用DISTINCT关键字后,工资SAL列中的重值并没有列入统计的范围之内。
另外还要强调一点,在所有5种聚合函数中,除了COUNT(*)函数外,其他的函数在计算过程中都忽略NULL值,即把NULL值的行排除在外,不进行分析。
8.2.6聚合函数的组合使用前面介绍的实例中,聚合函数都是单独使用的。
聚合函数也可以组合使用,即在一条SELECT语句中,可以使用多个聚合函数。
实例16使用多个聚合函数如下面的代码:SELECTCOUNT(*)ASnum_items,MAX(SAL)ASmax_sal,Min(AGE)ASmin_age,SUM(SAL)\\\/COUNT(SAL)ASavg_sal,AVG(DISTINCTSAL)ASdisavg_salFROMTEACHER运行结果如图8.17所示。
图8.17聚合函数的组合应用该例在一条SELECT语句中,几乎用到了所有的聚合函数。
其中num_items为TEACHER表所有记录的条目,max_sal为TEACHER表中记录的最高工资,min_age为TEACHER表中记录的最小年龄,avg_sal为所有TEACHER表中的工资记录的平均值,disavg_sal为TEACHER表中所有不同的工资记录的平均值。



