Access数据库技术与应用
上QQ阅读APP看书,第一时间看更新

3.3 通过设计视图编辑或创建查询

在查询设计视图中,可打开及修改用向导生成的查询,也可以直接建立新的查询。虽然“自动化”程度不如向导,但可以使查询具有更强的功能,如根据条件查询、按组查询以及使结果有序输出等。

3.3.1 通过设计视图编辑已有查询

1.在设计视图中完善简单查询

【例3-5】为例3-2建立的查询添加“博导”列(位于“职称”的右侧),用以说明该导师是否为博导,另存为“导师-研究生2”。

(1)在导航窗格中右击“导师-研究生”查询对象,在弹出的快捷菜单中选择“设计视图”命令,在查询设计视图中打开该查询,如图3-15所示。

图3-15 在查询设计视图中打开“导师-研究生”查询

(2)将光标置于“学号”字段之上,待光标变成“”形状后单击,选中“学号”列;然后单击“设计”选项卡中的“插入列”按钮,在“职称”与“学号”之间添加一个空列。

(3)在添加的空列中,单击第二行“表”列表框的下拉按钮,选择“导师”表;然后单击第一行“字段”列表框的下拉按钮,选择表中的“博导”字段,查询列添加即告完成,如图3-16所示。

图3-16 在设计视图中添加一个查询列的过程

(4)单击“设计”选项卡中的“运行”按钮,或通过“开始”/“设计”选项卡中的“视图”按钮切换到数据表视图,可以运行查询查看结果,如正确则选择“文件”菜单中的“对象另存为”命令,保存为“导师-研究生2”,然后关闭查询窗口。

说明:如果在“字段”下拉列表框中选择“导师.*”,则“导师”表的全部字段将被选中。

2.在设计视图中完善交叉表查询

观察例3-3生成的交叉表(见图3-13),可发现还有一些不尽如人意之处,如计算列的标题“总计入学分数”含义不清,应改成“入学平均分”;平均数的小数点位数太多,实际应用中只需保留两位小数即可,这些都需要在交叉表设计视图中予以改进。操作步骤如下:

(1)在导航窗格中右击“研究生_交叉表”查询对象,在弹出的快捷菜单中选择“设计视图”命令,打开“研究生_交叉表”设计视图,如图3-17所示。

图3-17 交叉表设计视图

(2)将最后一栏“总计入学分数”改为“入学平均分”,注意保留冒号“:”。

(3)将光标对准最后一栏并右击,在弹出的快捷菜单中选择“属性”命令,在属性表窗格的“常规”选项卡中,将“格式”设置为“固定”,“小数位数”设置为2,如图3-18所示;对“入学分数”字段属性也作相同的处理。编辑后的交叉表运行结果如图3-19所示。

图3-18 字段的属性表窗格

图3-19 编辑后的交叉表

3.3.2 通过设计视图创建新查询

使用查询设计视图创建查询首先要打开查询设计视图窗口,然后根据需要进行查询设置。

【例3-6】在查询设计视图中新建一个查询,要求能够显示各个系的系名、系中导师的姓名和导师所带的研究生姓名。本查询涉及3个表,事先应建立“系”表与“导师”表、“导师”表与“研究生”表之间的一对多关系。

(1)在数据库窗口中单击“创建”选项卡中的“查询设计”按钮,在打开的设计视图的“显示表”对话框中选择参与查询的数据源(表或/和查询)。本例先选定“系”,单击“添加”按钮,“系”表即出现在查询设计视图中;同理添加“导师”表和“研究生”表,如图3-20所示。也可以按住【Ctrl】键依次单击3个数据表表名,同时选定3个表,然后单击“添加”按钮。

图3-20 在“显示表”对话框中选择数据源

(2)单击“关闭”按钮关闭“显示表”对话框。如果再要添加数据源,可以在查询设计视图上半部分的空白处右击,在弹出的快捷菜单中选择“显示表”命令,再次打开“显示表”对话框。如果要删除某个数据源,则单击选定该数据源,按【Delete】键删除;如果数据源是多个,需注意多个数据源之间是否建立了关系,没有则需重新建立关系。

(3)在设计视图的下半部分从左到右依次打开“表”下拉列表框,分别选择“系”“导师”“研究生”表,在“字段”下拉列表框中分别选择“系”表的“系名”、“导师”表的“姓名”和“研究生”表的“姓名”字段,如图3-21所示。

(4)运行查询查看结果,如图3-22所示。注意查询结果仍为15行,因有3位研究生没有导师编号,无法归属到某位导师以及某个系。

(5)若运行正确,单击快速访问工具栏中的“保存”按钮保存编辑结果。

图3-21 在设计视图中决定需显示的字段

图3-22 查询执行结果

说明:

查询的“设计视图”窗口由两部分组成:

(1)上半部分:选择查询的数据源(数据表或查询),并列出数据源的所有字段及数据源之间的关系。

(2)下半部分:查询设计网格,用来指定具体的查询要求。每一列就是一个字段,每一行的含义如下:

①字段:选择要进行查询的字段名。

②表:指定字段名所来自的数据源。

③排序:查询结果是否按照该字段进行排序(升序、降序或不排序)。

④显示:设置该字段是否在查询结果中显示。

⑤条件:设置查询条件。

⑥或:逻辑“或”,是用于查询的第2个条件。

如果“系”表与“导师”表之间、“导师”表与“研究生”表之间没有建立关系,例3-6将得到什么结果呢?系统会这样判断:3个表各有自己的主键,且“系”表的主键“系编号”在“导师”表中作为非主键字段出现,同时“导师”表中“系编号”字段的数据符合参照完整性约束,系统会“猜测”它是一个外键;同理“研究生”表的“导师编号”也会被认为是外键,运行查询得到的结果与例3-6是一致的。

如果不修改数据与主键,在删除表间关系的前提下临时改变一下字段名:将“导师”表的“系编号”改为“系”,将“导师”表的“导师编号”改为“导师号”,则Access将无从判断谁是外键,只能进行广义笛卡儿积查询,将3个表连接成一个逻辑表,其记录数将达3×6×18=324个,这样的结果是没有任何实际意义的。

【例3-7】按系名显示各研究生的姓名。注:“系”表与“研究生”表之间并未建立一对多关系,但两者通过“导师”表存在着间接联系。

操作:在查询设计视图中同时显示“系”表、“导师”表和“研究生”表,选择“系”表的“系名”字段、“研究生”表的“姓名”字段,如图3-23所示(3位没有导师的研究生被排除在外)。本题操作的关键是:查询的数据源必须加上“导师”表,作为“系”表与“研究生”表之间联系的“桥梁”,否则两表之间没有直接联系,Access系统会进行广义笛卡儿积查询。

图3-23 例3-7的查询设计视图及执行结果

3.3.3 条件查询

条件的作用是对所选择的记录做进一步的限定,只有符合条件要求的记录才得以显示。通常条件是一个关系表达式或逻辑表达式,例如找出所有的女研究生,显示年龄大于60岁的导师,以及入学分数在200~300之间的研究生所对应的导师等。

【例3-8】显示所有女研究生的全部信息。

在设计视图中打开“研究生”表,在第1列中选择“研究生.*”字段,即记录的所有字段值都要显示;在第2列中选择“性别”字段,在“条件”文本框中输入一个条件“="女"”,并且不选定“显示”行的复选框。设计视图及执行结果如图3-24所示。

图3-24 女研究生信息的查询设计视图及执行结果

说明:

(1)字段只能通过设计视图的“字段”下拉列表框选取,无法用表达式选择。

(2)单个条件的格式:<表达式1><关系运算符><表达式2>,<表达式1>在设计视图中是指字段,省略。<关系运算符>是用于数据之间比较的运算符,其运行结果是逻辑值True/False,如表3-3所示;如果关系运算符是等号“=”,则可以省略。<表达式2>通常是一个常量,文本类型的常量必须放置在一对单引号或一对双引号中;日期类型的常量必须放置在一对#号中;是/否类型的常量用True/False、Yes/No或On/Off表示;数字类型的常量直接使用即可。本例的条件表示:="女",只有性别是“女”的记录才得以显示。

(3)由于第一列中的“*”表示全部字段,已经包含了性别内容,因此第二列中的“性别”字段只用于筛选记录,它的值已无必要显示,所以不选定“显示”行的复选框,以避免“性别”字段的重复显示。

【例3-9】列出入学分数在340~360之间的所有研究生的姓名、性别和入学分数。

设计视图及查询执行结果如图3-25所示。注意性别字段的“显示”被设置为

图3-25 例3-9的设计视图及运行结果

设计视图中,多个条件涉及相同的字段可以通过逻辑运算符(见表3-4)进行连接,例如本例;如果多个条件涉及不同的字段,则分别设置相应字段的条件,但需注意:同一行的多个条件是And关系(“与”运算),即几个条件同时成立,整个条件才成立;不同行的多个条件是Or关系(“或”运算),只要这些条件中的一个成立,条件就成立。见例3-10。

【例3-10】选出所有入学分数在340~360之间的男研究生的姓名、性别和入学分数。

本例的入学分数范围与性别要求同时成立,因此是And关系,必须写在同一行中。设计视图及查询执行结果如图3-26所示。

图3-26 例3-10的设计视图及运行结果

【例3-11】选出研究方向为考古学或会计学的所有研究生的姓名、性别、入学分数和研究方向。

本例的研究方向要求是“考古学或会计学”,设计视图及查询执行结果如图3-27所示。当然也可以在“条件”文本框中填写“"考古学"Or"会计学"”。

图3-27 例3-11的设计视图及运行结果

【例3-12】显示导师“马腾跃”所带的全部女研究生以及入学分数超过340分的男研究生的相关信息。

本例的设计视图及查询执行结果如图3-28所示。注意“马腾跃”必须上下出现两次,如果省略下面的“马腾跃”,查询的含义就变成显示马腾跃所带的全部女研究生,以及不分导师、入学分数在340以上的全部男同学。

图3-28 例3-12的设计视图及运行结果

【例3-13】找出所有没有分配导师的研究生姓名。

文本型字段如果没有值,则其值为空,但查询时不能在“条件”文本框中输入“=''”(两个单引号)或“=""”(两个双引号),而应该使用表达式“IsNull”。本例的设计视图及查询执行结果如图3-29所示。

图3-29 例3-13的设计视图及运行结果

3.3.4 查询的有序输出

默认情况下,查询输出时数据自上而下的排列顺序与数据表中的顺序一致。为便于浏览,可以指定查询的输出按某些字段值的大小升序或降序排列显示,设计视图中的“排序”下拉列表框中有3个选项:升序、降序和不排序(默认)。如果有多个字段都是排序关键字段,则Access按从左到右的顺序依次进行排序。

【例3-14】建立一个查询,用于输出“研究生”表中的姓名、性别、导师编号和入学分数,要求按性别的升序和导师编号的降序显示记录。

设计视图和显示结果如图3-30所示。“性别”字段选择了升序(第一排序关键字),“导师编号”作为第二排序关键字选择了降序,排序结果表明:记录首先按性别从小到大分成男、女两类(按拼音顺序),每一类又根据导师编号值从大到小显示,以空值为最小。

图3-30 例3-14的设计视图及运行结果

【例3-15】要求同例3-14,但输出时字段的排列顺序为姓名、导师编号、性别和入学分数。

本题不能简单地交换“导师编号”字段和“性别”字段,因为系统总是先对左端的字段排序,这样第一排序关键字将变成“导师编号”。解决的方法是:仍按题目要求安排字段次序,但不针对“导师编号”字段排序,另外添加一个不显示的字段“导师编号”用于排序,如图3-31所示。

图3-31 例3-15的设计视图

3.3.5 使用通配符查询

在很多场合,我们无法做到一字不漏地记忆完整的信息,通常只是一个大概,如只记得某人姓“马”,一本书的书名中包含“数据库应用”几个字等,在Access中要完成对这些残缺信息的查询需借助于通配符。这种查询又称模糊查询。

通配符可以用作其他字符的占位符,用以实现在仅知部分内容的情况下完成对文本、数值等类型字段的查询。在Access中,默认使用MicrosoftJet数据库引擎SQL通配符,其符号、作用与示例如表3-1所示。

表3-1 MicrosoftJet数据库引擎SQL通配符

【例3-16】找出所有研究方向的第3个字为“医”的所有姓马的研究生的全部信息。

在查询设计视图的“条件”中应用通配符时,注意运算符不能使用“=”,而要用Like,如图3-32所示。

【例3-17】找出年龄为50余岁的导师,要求其所带的研究生中没有姓马、姓赵的学生。

设计视图如图3-33所示。

图3-32 例3-16的设计视图

图3-33 例3-17的设计视图

系统还提供了使用ANSI-92通配符的方法,这些通配符与Microsoft SQL Server语法兼容。切换的方法是:选择“文件”菜单中的“选项”命令,在左侧窗格中选择“对象设计器”,在右侧窗格的“SQL Server兼容语法(ANSI92)”选项组中选中“此数据库”复选框,如图3-34所示。

图3-34 选择ANSI-92通配符

Microsoft Jet SQL通配符与ANSI-92通配符的区别在于:后者用%表示任意个数的字符,用_表示单个字符,用^排除不包含在方括号中的字符。因此ANSI-92中的%、_、^分别对应Microsoft Jet通配符中的*、?、!。

说明:MicrosoftJet数据库引擎SQL属于ANSI-89Level1,Access能够支持ANSI-89SQL和SQL-92SQL,但不能同时支持两者,在默认情况下Access使用ANSI-89。如果希望在将来要将应用程序升迁为Access项目,或者要使用GRANT和REVOKE(授权与撤销权限)语句,则可以使用ANSI-89SQL语法。

3.3.6 使用计算字段

计算字段不是数据表中真正的字段,它的值由表达式计算而得,本身并不保存在表中。一旦表达式中引用的字段或值发生了变化,就必须再次执行查询,重新计算该字段的值。

【例3-18】输出导师的编号、姓名、出生年份和性别。

“导师”表中并没有记录各位导师的出生年份,但有导师“年龄”字段。因此,可通过导师年龄和今年(2015年)的年份推算出导师的出生年份,即“出生年份=2015-[年龄]”,设计视图如图3-35所示。

图3-35 设置导师“出生年份”计算字段及执行结果

从图3-35(a)的设计视图来看,第3个字段为“出生年份:2015-[年龄]”,“:”前是字段名,可以自己命名;“:”后是表达式,是该计算字段的计算公式。Access允许字段名中保留空格,引用时需用[]括起以表明是一个完整的标识符,例如,假定“导师”表中字段名“姓名”中间有两个空格,引用时应写成“[姓名]”。如果写成“姓名”,Access会认为是两个字段“姓”和“名”,事实上不存在这两个字段,系统报错。

从图3-35(b)的查询结果来看,形式上“出生年份”与一般的数据表字段并无差别,但该列数据并不保存在导师表中。本例中的计算字段表达式只适合在2015年计算导师年龄,到2016年就需要对表达式作修改,改进的方法是用日期/时间函数Date()取当前日期,再用Year()函数从中取出年份,然后减去导师的年龄,即Year(Date())-[年龄],就可以一劳永逸地使用这个表达式。

用运算符将常量、变量、函数连接起来的式子称为表达式,表达式计算将产生一个结果。利用表达式可以设置字段的有效性规则(见2.2.1节)、在查询中设置条件(见3.3.3节)或定义计算字段。

1.常用运算符

运算符是表示实现某种运算的符号。Access系统提供了算术运算符(见表3-2)、关系运算符(见表3-3)、逻辑运算符(见表3-4)和连接运算符(见表3-5)。

表3-2 算术运算符

表3-3 关系运算符

表3-4 逻辑运算符

表3-5 连接运算符

2.常量

文本类型的常量必须使用一对单引号或一对双引号进行定界,例如:"男"、"教授"、"马腾跃"等。

日期类型的常量必须使用一对#号进行定界,例如:#11-5-2015#、#2015-11-5#等。

是/否类型的常量用True/False、Yes/No或On/Off表示。

数字类型的常数直接使用即可。

3.变量

字段就是变量的一种,在表达式中表示最好用方括号[]括起来,例如:[姓名]、[性别]等。用[]括起可以表明这个变量是一个完整的标识符,防止Access系统误判。

4.函数

Access提供了大量的系统预先定义好的函数(又称标准函数),用户使用时只需给出相应的参数值即可自动完成计算。这些函数可以分为数学函数(见表5.2)、字符串处理函数(见表5.3)、日期/时间函数(见表5.4)、聚合函数(见3.4.4节)等,其中聚合函数可直接用于查询中。

3.3.7 使用参数查询

参数查询是一种动态查询,可以在每次运行查询时输入不同的参数值,Access系统据此确定查询结果,而参数值在创建查询时无须定义。这种查询完全由用户控制,能一定程度上适应应用的变化需要,提高查询效率。根据查询中参数个数的不同,参数查询可以分为单参数查询和多参数查询。

【例3-19】按姓名模糊查询研究生的所有信息。

查询设计视图如图3-36所示,在“姓名”字段的条件行中输入“Like"*"&[输入要查询的研究生姓名]&"*"”,其中[输入要查询的研究生姓名]是参数,实际上就是一个变量,在运行查询时系统会弹出“输入参数值”对话框。如果输入“马”,则用参数值“马”取代参数[输入要查询的研究生姓名],“姓名”字段的查询条件就变成“Like"*马*"”,系统据此确定查询结果,显示马力、马德里、马德望和司马倩四位研究生的全部信息。

图3-36 查询设计视图(1个参数)及输入参数值

说明:Access系统是如何判断[名称]是参数?还是字段?判断的依据就是:如果[]内的名称是查询数据源中的字段名,则Access系统判断[名称]是字段,否则就是参数。

【例3-20】在给定的入学分数最低分和最高分之间查询研究生的姓名、年级、入学分数和导师的姓名。查询设计视图如图3-37所示。

图3-37 查询设计视图(2个参数)

其中,“年级”字段不存在,采用计算字段来实现,表达式“Mid([学号],1,2)”的功能是取“学号”字段的前2位,因为学号的前2位表示年级。在“入学分数”字段的条件行中输入“>=[最低分]And<=[最高分]”,其中[最低分]和[最高分]都是参数。在运行查询时系统会分别弹出“输入参数值”对话框要求输入具体的参数值,如图3-38所示。如果[最低分]输入“340”,[最高分]输入“350”,则“入学分数”字段的查询条件就变成“>=340And<=350”,系统据此确定查询结果。

图3-38 输入参数值