1.37k likes | 1.59k Views
第五章 关系数据库标准语言 SQL. SQL 是 Structured Query Language 的缩写,即结构化查询语言。它是关系数据库的标准语言。查询是 SQL 语言的重要组成部分, SQL 还包含数据定义、数据操作和数据控制功能等内容。 SQL 已经成为关系数据库的标准数据语言,所以现在所有的关系数据库管理系统都支持 SQL 。掌握 SQL 语法可以更加灵活地建立查询和视图。. 5.1 SQL 简介.
E N D
SQL是Structured Query Language的缩写,即结构化查询语言。它是关系数据库的标准语言。查询是SQL语言的重要组成部分,SQL还包含数据定义、数据操作和数据控制功能等内容。SQL已经成为关系数据库的标准数据语言,所以现在所有的关系数据库管理系统都支持SQL。掌握SQL语法可以更加灵活地建立查询和视图。
5.1 SQL简介 • SQL语言来源于20世纪70年代IBM的一个被称为SEQUEL(Structured English Query Language)的研究项目。20世纪80年代,SQL由ANSI进行了标准化,它包括了定义和操作数据的指令。由于它具有功能丰富、使用方式灵活、语言简洁易学等突出特点,在计算机界深受广大用户欢迎,许多数据库生产厂家都相继推出各自支持SQL标准。1998年4月,ISO提出了具有完整性特征的SQL,并将其定为国际标准,推荐它为标准关系数据库语言。1990年,我国也颁布了《信息处理系统数据库语言SQL》,将其定为中国国家标准。
5.1.1 SQL语言的主要特点 • (1)一体化语言。SQL提供了一系列完整的数据定义、数据查询、数据操作和数据控制等方面的功能。用SQL可以实现数据库生命周期中的全部活动,包括简单地定义数据库和表的结构,实现表中数据的录入、修改、删除、查询和维护,数据库重构、数据库安全控制等一系列操作要求。 • (2)高度非过程化。SQL和其他数据操作语言不同,SQL是一种非过程性语言,它不必一步步地告诉计算机“如何”去做,用户只需说明做什么操作,而不用说明怎样做,不必了解数据存储的格式及SQL命令的内部,就可方便地对关系数据库进行操作。 • (3)语言简洁。虽然SQL的功能很强大,但语法却很简单,只有为数不多的几条命令。表给出了分类的命令动词,从该表可知,它的词汇很少。初学者经过短期的学习就可以使用SQL进行数据库的存取等操作,因此,易学易用是它的最大特点。 • (4)统一的语法结构对待不同的工作方式。SQL语言可以直接在VFP的命令窗口以人机交互的方式使用,也可嵌入到程序设计中以程序方式使用,比如,SQL语言写在.PRG文件中也能运行。在书写的时候,如果语句太长,可以用“;”号换行。现在很多数据库应用开发工具都将SQL语言直接融入到自身的语言之中,使用起来更方便,VFP就是如此。这些使用方式为用户提供了灵活的选择余地。此外,尽管SQL的使用方式不同,但SQL语言的语法基本是一致的。
5.1.2 SQL语句的执行 • SQL语句可以在命令窗口中执行,也可以作为查询或视图(的内容)被使用,还可以在程序文件被执行。 • 表5.1 SQL命令动词 • —————————————————————— • SQL功能 命令动词 • —————————————————————— • 数据查询 SELECT • 数据定义 CREATE、DROP、ALTER • 数据操作 INSERT、UPDATE、DELETE • 数据控制 GRANT、REVOKE • ——————————————————————
5.2 查询功能 • 数据库中最常见的操作是数据查询,也是SQL的核心。
5.2.1 SQL语法 • SQL给出了简单而又丰富的查询语句形式,SQL的查询命令也称作SELECT命令,它的基本形式由SELECT-FROM-WHERE查询块组成,多个查询块可以嵌套执行。 • 格式: • SELECT [ALL|DISTINCT][ TOP〈表达式〉 ] • [ 〈别名〉 ] 〈Select表达式〉 [AS 〈列名〉 ][, [ 〈别名〉 ] • 〈Select表达式〉 [AS 〈列名〉 ]…] • FORM[ 〈数据库名〉 !] 〈表名〉 [[AS]Local_Alias] • [[INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] • JOIN[ 〈数据库名〉 !] 〈表名〉 [[AS]Local_Alias][ON〈联接条件〉 ]] • [INTO 〈查询结果〉 |TO FILE 〈文件名〉 [ADDITIVE] • | TO PRINTER [PROMPT] | TO SCREEN] • [PREFERENCE PreferenceName][NOCONSOLE][PLAIN][NOWAIT] • [WHERE 〈联接条件1〉 [AND 〈联接条件2〉…][AND | OR 〈筛选条件〉 … • ]] • [GROUP BY 〈组表达式〉 ][, 〈组表达式〉 …]] • [HAVING ]〈筛选条件〉 ] • [UNION [ALL] 〈SELECT命令〉 ] • [ORDER BY 〈关键字表达式〉 [ASC |DESC] [, 〈关键字表达式〉 • [ASC |DESC]…]] • 说明:SELECT-SQL命令的格式包括三个基本子句:SELECT子句、FROM子句、WHERE子句,还包括操作子句:ORDER子句、GROUP子句、UNION子句以及其他一些选项。
1.SELECT子句 • SELECT子句用来指定查询结果中的数据。其中: • ALL选项:表示选出的记录中包括重复记录,这时缺省值;DISTINCT则表示选出的记录中不包括重复记录。 • TOP〈表达式〉选项:表示在符合条件的记录中,选取指定数量或百分比(〈表达式〉)记录。[〈别名〉]〈Select表达式〉[AS〈列名〉]选项中的别名是字段所在的表名;〈Select表达式〉,可以是字段名或字段表达式;〈列名〉用于指定输出时使用的列标题,可以不同于字段名。 • 〈Select表达式〉用一个*号来表示时,指定所有的字段。
2.FROM子句 • 用于指定查询的表与联接类型。其中: • JOIN关键字用于联接其左右两个〈表名〉所指定的表。INNER | LEFT[OUTER] | RIGHT[OUTER] | FULL[OUTER]选项,指定两表联接时的联接类型,联接类型有4种,如表5.2所示。其中的OUTER选项,表示外部联接,即允许满足联接条件的记录,又允许不满足联接条件的记录。若省略OUTER选项,效果不变。
表5.2 联接类型 • —————————————————————————————————— • 联接类型 意义 • —————————————————————————————————— • Inner Join(内部联接) 只有满足联接条件的记录包含在结果中 • Left Outer Join(左联接) 左表某记录与右表所有记录比较字段值,若有满足联接条件的,则产生一个真实记录;若都有满足,则产生一个含.NULL值的记录。直到右表所有记录都比较完 • Right Outer Join(右联接) 右表某记录与左表所有记录比较字段值,若有满足联接条件的,则产生一个真实记录;若都不满足,则产生一个含.NULL值的记录。直到右表所有记录都比较完 • Full Jion(完全联接) 先按右联接比较字段值,再按左联接比较字段值。不列入重复记录 • ————————————————————————————————————— • ON选项:用于指定联接条件。 • INTO与TO选项:用于指定查询结果的输出去向,默认查询结果显示在浏览窗口中。INTO选项中的 〈查询结果〉 有3种,如表5.3所示。
5.3 查询结果 • ———————————————————— • 目标 输出形式 • ————————————————————— • ARRAY〈数组〉 查询结果输出到数组 • CURSOR〈临时表〉 查询结果输出到临时表 • TABLE | DBF〈表名〉 查询结果输出到表 • ————————————————————— • TO FILE选项: • 表示输出到指定的文本文件,并取代原文件内容。 • ADDITIVE选项:表示只添加新数据,不清除原文件的内容。 • TO PRINTER选项:表示输出到打印机。 • PROMPT选项:表示打印前先显示打印确认框。 • TO SCREEN选项:表示输出到屏幕。 • PLAIN选项:表示输出时省略字段名。 • NOWAIT选项:表示显示浏览窗口后程序继续往下执行。
3.WHERE子句 • 用来指定查询的条件。其中的 〈联接条件〉 指定一个字段,该字段连接FROM子句中的表。 • 如果查询中包含不止一个表,就应该为第一个表后的每一个表指定连接条件。
4.其他子句和选项 • GROUP BY子句:对记录按〈组表达式〉值分组,常用于分组统计。 • HAVING子句:当含有GROUP BY子句时,HAVING子句可用作记录查询的限制条件;无GROUP BY 子句时,HAVING子句的作用如同WHERE子句。 • UNION子句:可以用UNION子句嵌入另一个SELECT-SQL命令,使这两个命令的查询结果合并输,但输出字段的类型和宽度必须一致。UNION子句默认组合结果中排除重复行,使用ALL,则允许包含重复行。 • ORDER BY子句:指定查询结查中记录按〈关键字表达式〉排序,默认升序。选项ASC表示升序,DESE表示降序。 • SELECT查询命令的使用非常灵活,用它可以构造各种各样的查询。本章将通过大量的实例来介绍SELECT命令的使用方法。
5.2.2 简单查询 • 简单查询只含有基本子句,可有简单的查询条件。 • 【5.1】在zgda表中,检索所有字段。 • SELECT * FROM zgda
5.2.2 简单查询 • 【5.2】在zggz表中,检索实发工资大于2000元的记录。 • SELECT 编号,姓名,实发工资 FROM zggz WHERE 实发工资>2000
5.2.2 简单查询 • 【5.3】在zgda表中,检索所有职称名称。 • SELECT DISTINCT 职称 FROM zgda • 【5.4】在zgda表中,检索职称是助教的记录。 • SELECT 编号,姓名,职称 FROM zgda WHERE 职称="助教"
5.2.2 简单查询 • 【5.5】在zggz表中,检索实发工资小于1000大于1800元的记录。命令执行结果如图5.5所示。 • SELECT 编号,姓名,实发工资 FROM zggz WHERE 实发工资>1000 AND 实发工资<1800
5.2.3 几个特殊运算符 • 在SQL语句中,WHERE子句后面的联接条件,除了可以使用VFP语言中的关系表达式以及逻辑表达外,还可以使用几个特殊运算符: • (1)[NOT]IN:表示[不]在…之中。 • (2)[NOT]BETWEEN…AND…:表示[不]在…之间。 • (3)[NOT]LIKE:表示[不]与…匹配。
5.2.3 几个特殊运算符 • 下面以实例来说明此用法。 • 说明: • (1)NOT运算符来设计否定条件。 • (2)LIKE运算符提供两种字符串匹配方式,一种是使用下划线符号“_”,匹配一个和任意字符,另一种是使用百分号“%”,匹配0个或多个任意字符。 • (3)IN运算符,格式为IN(常量1,常量2,…)。含义为查找和常量相等的值。
5.2.3 几个特殊运算符 • 【5.6】在zgda表中,检索性别是男的记录。 • SELECT DISTINCT 编号,姓名,性别 FROM zgda WHERE 性别 LIKE "男" • 可以使用NOT运算符来设计否定条件,检索性别不是男的记录。 • SELECT DISTINCT 编号,姓名,性别 FROM zgda WHERE NOT(性别 LIKE "男")
5.2.3 几个特殊运算符 • 【5.7】在zgda表中,检索所有姓刘的记录。 • SELECT 编号,姓名 FROM zgda WHERE 姓名 LIKE "刘%"
5.2.3 几个特殊运算符 • 【5.8】在zgda表中,检索所有姓陈和姜的记录。 • SELECT 编号,姓名 FROM zgda WHERE 姓名 IN("陈","姜") • 上式可以改为VFP条件,执行结果是一样的。 • SELECT 编号,姓名 FROM zgda WHERE 姓名="陈" OR 姓名="姜" • 图5.8
5.2.4 简单的联接查询 • 联接是关系的基本操作之一,联接查询是一种基于多个关系的查询。 • 【5.9】在zgda表和zggz表中,检索实发工资大于2000元的记录。 • 3.9所示。 • SELECT zgda.编号,zgda.姓名,zggz.实发工资 FROM zgda,zggz; • WHERE (实发工资>2000) AND (zgda.编号=zggz.编号) • zgda.编号=zggz.编号 &&编号是联接的条件
5.2.4 简单的联接查询 • 【5.10】在zgda表和zggz表中,检索职称是讲师, 并且实发工资大于1900元的记录 SELECT zgda.编号,zgda.姓名,zgda.职称,zggz.实发工资 FROM zgda,zggz; • WHERE (职称="讲师") AND (实发工资>1900) AND (zgda.编号=zggz.编号)
5.2.5 嵌套查询 • 嵌套查询是基于多个关系的查询,这类查询所要求的结果出自一个关系,但相关条件却涉及多个关系。这时就需要使用SQL的嵌套查询功能。 • 格式: 〈表达式〉〈比较运算符〉[ANY|ALL|SOME](〈子查询〉) • [NOT]EXISTS (〈子查询〉) • 说明: • (1)其中的〈比较运算符〉除了在第6章介绍的关系运算符之外,还有前面提到的特殊运算符。 • (2)ANY、ALL、SOME是量词,其中ANY和SOME是同义词,在进行比较运算时只要子查询中有一条记录为真,则结果为真;而ALL则要求子查询中的所有记录都为真,结果才为真。 • (3)EXISTS是谓词,用来检查子查询中是否有结果返回(是否为空)。NOT EXISTS表示是空的结果集。
5.2.5 嵌套查询 • 为了讨论嵌套查询,在此引入一个订货管理数据库,此数据库涉及4个表(4 个关系),即仓库表、职工表、订购单表、供应商表,4个表的内容分别如图5.11、5.12、5.13、5.14所示。
5.2.5 嵌套查询 • 【5.11】在仓库表和职工表中,检索哪些城市至少有一个仓库的职工工资为1250元 • SELECT 城市 FROM 仓库 WHERE 仓库号 IN; • (SELECT 仓库号 FROM 职工 WHERE 工资=1250) • 在这个命令中含有两个SELECT-FROM-WHERE查询块,即内层查询块和外层查询块,内层查询块 • 检索到的仓库号值是WH1和WH2, 这里IN相当于集合运算符∈。这样就可写出等价的命令: • SELECT 城市 FROM 仓库 WHERE 仓库号 IN("WH1", "WH2")
5.2.5 嵌套查询 • 【5.12】在仓库表和职工表中,检索所有职工的工资都多于为1210元的仓库信息。 • SELECT * FROM 仓库 WHERE 仓库号 NOT IN; • (SELECT 仓库号FROM职工 WHERE工资<=1210)
5.2.5 嵌套查询 • 内层SELECT-FROM-WHERE查询块指出所有职工的工资少于或等于1210元的仓库的仓库号值的集合,在这里该集合只有一个值“WH1”;然后从仓库关系中检索元组的仓库号属性值不在该集合中的每个元组。有的读者也许已经注意到刚才的检索出现了错误,尽管在“武汉”的“WH4”仓库还没有职工,但该仓库的信息也被检索出来了。所以必须认真分析检索要求,写出正确的SQL命令。如果要求排除那些还没有职工的仓库,检索要求可以叙述为:检索所有职工的工资都多于1210元的仓库的信息,并且该仓库至少要有一名职工。这样描述就很清楚了,因为我们对没有职工的仓库不感兴趣。这样,写出的SQL命令也就复杂一些了: • SELECT * FROM 仓库 WHERE 仓库号 NOT IN; • (SELECT 仓库号 FROM 职工 WHERE 工资<=1210); • AND 仓库号 IN(SELECT 仓库号 FROM 职工) • 这样内层是两个并列的查询,在结果中将不包含没有职工的仓库信息。
5.2.5 嵌套查询 • 【5.13】检索出和职工E4挣同样工资的所有职工。 • SELECT 职工号 FROM 职工 WHERE 工资=; • (SELECT 工资 FROM 职工 WHERE 职工号="E4")
5.2.5 嵌套查询 • 【5.14】检索出工资在1220元到1240元范围内的职工信息。这个查询的条件值是在什么范围之内,显然可以用BETWEEN…AND…,为此有如下查询语句: • SELECT * FROM 职工WHERE工资 BETWEEN 1220 AND 1240这里BETWEEN…AND…意思是在“…和…之间”,这个查询的条件等价于: • (工资>=1220) AND (工资<=1240) • 显然使用BETWEEN…AND…表达条件更清晰、更简洁。假如找出工资不在1220元和1240元之间的全部职工信息,可以用命令: • SELECT * FROM 职工 WHERE工资 NOT BETWEEN 1220 AND 1240命令执行结果如图5.20所示。
5.2.5 嵌套查询 • 【5.15】在供应商表中,检索出全部公司的信息,不要工厂或其他供应商的信息。这是一个字符串匹配的查询,显然应该使用LIKE运算符: • SELECT * FROM 供应商 WHERE 供应商名 LIKE "%公司" • 这里的LIKE是字符串匹配运算符,通配符“%”表示0个或多个字符,另外还有一个通配符“-”表示一个字符。
5.2.5 嵌套查询 • 【5.16】在供应商表中,找出不在北京的全部供应商的信息。 • SELECT * FROM 供应商 WHERE 地址!="北京" • 在SQL中,“不等于”用“!=”表示。另外还可以用否定运算符NOT写出等价命令: • SELECT * FROM 供应商 WHERE NOT(地址="北京") • NOT的应用范围很广,比如,可以有NOT IN(例5.12)、NOT BETWEEN等。
5.2.6 排序 • SQL中排序操作使用ORDER BY子句。 • 格式:ORDER BY 〈关键字表达式1〉 [ASC | DESC][, 〈关键字表达式2〉 [ASC | DESC]…] • 说明:ASC为升序(默认为升序),DESC为降序。允许按一列或多列排序。
5.2.6 排序 • 【5.17】在职工表中,按职工的工资值升序检索出全部职工的信息。 • SELECT * FROM 职工 ORDER BY 工资 • 这里ORDER BY是排序子句,如果需要将结果按降序排列,只要加上DESC。 • SELECT * FROM 职工 ORDER BY 工资 DESC
5.2.6 排序 • 【5.18】在职工表中,先按仓库号排序,再按工资排序,并输出全部职工信息。 • SELECT * FROM 职工 ORDER BY 仓库号,工资 • 这里一个按多列排序的例子。 • 说明:ORDER BY是对最终的查询结果进行排序,不可以在子查询中使用该短语。
5.2.7 简单的计算查询 • SQL语言是完备的,也就是说,只要数据是按关系方式存入数据库的,就能构造合适的SQL命令把它检索出来。事实上,SQL不仅具有一般的检索能力,而且还有计算方式的检索,比如检索职工的平均工资、检索某个仓库中职工的最高工资值等。用于计算检索的函数有: • (1)COUNT—计数 • (2)SUM—求和 • (3)AVG—计算平均值 • (4)MAX—求最大值 • (5)MIN—求最小值 • 这些函数可以用在SELECT短语中对查询结果进行计算。
5.2.7 简单的计算查询 • 【5.19】在供应商表中,找出供应商所在地的数目。 • SELECT COUNT (DISTINCT 地址) FROM 供应商 • 参见前面给出的供应商的记录值,其中共有5个地址:北京、西安、郑州、上海和深圳。所以结果为5。 • 说明,除非对关系中的元组个数进行计数,一般应用COUNT函数应该使用DISTINCT。例如: • SELECT COUNT(*) FROM 供应商 • 将给出供应商关系中的记录数是6个。
5.2.7 简单的计算查询 • 【5.20】在职工表中,求支付的工资总数。 • SELECT SUM(工资) FROM 职工 • 结果是:6160。这个结果是职工关系中的工资值的总和,它并不管是否有重复值。这时若使用命令: • SELECT SUM(DISTINCT工资) FROM 职工 • 将得出错误的结果4910。原因是DISTINCT命令去掉重复值1250。
5.2.7 简单的计算查询 • 【5.21】在职工表和仓库表中,求北京和上海的仓库职工的工资总和。 • SELECT SUM(工资) FROM 职工WHERE仓库号IN; • (SELECT 仓库号 FROM 仓库 WHERE 城市="北京" OR 城市="上海")
5.2.7 简单的计算查询 • 5.22 在仓库表和职工表中,求所有职工的工资都多于1210元的仓库的平均面积。 • SELECT AVG(面积) FROM 仓库 WHERE 仓库号 NOT IN; • (SELECT 仓库号 FROM 职工 WHERE 工资<=1210) • 结果是:366.67 • 这里要注意,以上结果的运算包含了尚没有职工的WH4仓库。如果要排除没有职工的仓库,以上语句应该改为: • SELECT AVG(面积) FROM 仓库 WHERE 仓库号 NOT IN; • (SELECT 仓库号 FROM 职工 WHERE 工资<=1210); • AND仓库号 IN (SELECT仓库号 FROM 职工)
5.2.7 简单的计算查询 • 【5.23】在职工表中,求在WH2仓库工作的职工的最高工资值。 • SELECT MAX(工资) FROM 职工 WHERE 仓库号="WH2" • 结果是:1250 • 与MAX函数相对应的是MIN函数(求最小值)。比如,求最低工资值可以有如下命令: • SELECT MIN(工资) FROM 职工 WHERE仓库号="WH2"
5.2.8 分组与计算查询 • 上面几个例子是对整个关系的计算查询,而利用GROUP BY子句可以进行分组计算查询,使用得更加广泛。格式:GROUP BY 〈分组字段名〉[〈分组字段名〉…][HAVING〈过滤条件〉]可以按一列或多列分组,还可以用HAVING进一步限定分组的条件。下面是几个分组计算查询的例子。
5.2.8 分组与计算查询 • 【5.24】在职工表中,求每个仓库的职工的平均工资。 • SELECT 仓库号,AVG(工资) FROM 职工 GROUP BY 仓库号 • 在这个查询中,首先按仓库号属性进行分组,然后再计算每个仓库的平均工资。GROUP BY子句一般跟在WHERE子句之后,没有WHERE子句时,跟在FROM子句之后。另外,还可以根据多个属性进行分组。在分组查询时,有时要求分组满足某个条件时才检索,这时可以用HAVING子句来限定分组。
5.2.8 分组与计算查询 • 【5.25】在职工表中,求至少有两个职工的每个仓库的平均工资。 • SELECT 仓库号,COUNT(*),AVG(工资) FROM职工; • GROUP BY 仓库号 HAVING COUNT(*)>=2 • HAVING子句总是跟在GROUP BY 子句之后,不可以单独使用。HAVING子句和WHERE 子句不矛盾,在查询中是先用WHERE子句限定元组,然后再进行分组,最后再用HAVING子句限定分组。 • 说明:HAVING子句和WHERE子句的区别:WHERE子句是用来指定表中各行所应满足的条件,而 • HAVING子句是用来指定每一分组所满足的条件,只有满足HAVING条件的那些组才能在结果中被显示。
5.2.9 别名的使用 • 在联接操作中,经常需要使用关系名作前缀,有时这样显得很麻烦。因此,SQL允许在FROM短语中为关系名定义别名。 • 格式:〈关系名〉〈别名〉 • 例如:如下的联接语句是一个基于4个关系的联接查询,其中必须使用关系名作前缀: • SELECT 供应商名 FROM 供应商,订购单,职工,仓库; • WHERE 地址="北京" AND 城市="北京"; • AND 供应商.供应商号=订购单.供应商号; • AND 订购单.职工=职工.职工号; • AND 职工.仓库号=仓库.仓库号
5.2.9 别名的使用 • 在上面的查询中,如果使用别名就会简单一些,如下是使用了别名的同样的联接查询语句: • SELECT 供应商名 FROM 供应商 S,订购单 P,职工 E,仓库 W; • WHERE 地址="北京"AND 城市="北京"; • AND S.供应商号=P.供应商号; • AND P.职工号=E.职工号; • AND E.仓库号=W.仓库号 • FROM 供应商 S,订购单 P,职工 E,仓库 W,用S、P、E和W分别代表供应商表、订购单表 • 、职工表和仓库表。 • 说明:在嵌套的SQL子句中不能使用外层定义的别名。
5.2.10 内外层互相关嵌套查询 • 嵌套查询都是外层查询依赖于内层查询的结果,而内层查询与外层查询无关。事实上,有时也需要内、外层互相关的查询,这时内层查询的条件需要外层查询提供值,而外层查询的条件需要内层查询的结果。
5.2.10 内外层互相关嵌套查询 • 【5.26】在订购单表中,列出每个职工经手的具有最高总金额的订购单信息。这里先给出相应的查询语句,然后再作必要的解释。 • SELECT out.职工号,out.供应商号,out.订购单号,out.订购日期,out.总金额; • FROM 订购单 out WHERE 总金额=(SELECT MAX(总金额) FROM 订购单 inner1; • WHERE out.职工号=inner1.职工号)
5.2.10 内外层互相关嵌套查询 • 在这个查询中,外层查询和内层查询使用同一个关系:订购单表,给他们分别指定别名out和inner1。外层查询提供out关系中每个元组的职工号值给内层查询使用;内层查询利用这个职工号值,确定该职工经手的具有最高总金额的订购单和总金额;随后外层查询再根据out关系的同一元组的总金额与该总金额值进行比较,如果相等,则该元组被选择。