SQL语言入门教程


Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 1 结构化查询语 言 SQL SQL SQL SQL 入门教程 第一部分:组织数据 .........................................................................................................................2 SQL 入门 :表...............................................................................................................................2 SQL 入门 :视图 ...........................................................................................................................2 SQL 入门 :模式 ...........................................................................................................................3 SQL 入门 :数据类型 ...................................................................................................................3 第二部分:创建表和视图 .................................................................................................................6 SQL 入门 :创建表 .......................................................................................................................6 SQL 入门 :插入数据 ...................................................................................................................7 SQL 入门 :更改数据 ...................................................................................................................9 SQL 入门 :删除数据 .................................................................................................................10 SQL 入门 :创建视图 .................................................................................................................10 第三部分:使用 SQL 语句存取数据 ...........................................................................................13 SQL 入门 :选择列 .....................................................................................................................13 SQL 入门 :选择行 .....................................................................................................................15 SQL 入门 :将行进行排序 .........................................................................................................17 SQL 入门 :除去重复行 .............................................................................................................19 SQL 入门 :运算次序 .................................................................................................................19 SQL 入门 :使用表达式来计算值 .............................................................................................20 SQL 入门 :给表达式命名 .........................................................................................................21 SQL 入门 :从多个表中选择数据 .............................................................................................21 SQL 入门 :使用子查询 .............................................................................................................23 SQL 入门 :使用函数 .................................................................................................................23 SQL 入门 :用户定义函数 .........................................................................................................26 SQL 入门 :分组 .........................................................................................................................27 第四部分:表达式和子查询 ...........................................................................................................29 SQL 入门 :标量全查询 .............................................................................................................29 SQL 入门 :转换数据类型 .........................................................................................................30 SQL 入门 :条件表达式 .............................................................................................................30 SQL 入门 :表表达式 .................................................................................................................32 SQL 入门 :相关名 .....................................................................................................................34 相关子查询 ...............................................................................................................................35 SQL 入门 :用集合运算符组合查询 .........................................................................................40 第五部分:在查询中使用运算符和谓词 .......................................................................................42 SQL 入门 :用集合运算符组合查询 .........................................................................................43 SQL 入门 :谓词 .........................................................................................................................46 第六部分:高级 SQL.....................................................................................................................49 SQL 入门 :用约束和触发器实施商业规则 .............................................................................49 SQL 入门 :连接 .........................................................................................................................55 SQL 入门 :复杂查询 .................................................................................................................59 第七部分:定制和增强数据操作 ...................................................................................................60 SQL 入门 :用户定义类型 .........................................................................................................60 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 2 SQL 入门 :大对象 (LOB)........................................................................................................ 61 SQL 入门 :目录视图的介绍 .....................................................................................................62 注:文章来源为 chinaitlab 技术专题,作者未知,在些致谢,转载请尊重原作者的权益,注 意保留信息的完整性。 第一 部分 : 组织 数据 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 表表表 表 表是由定义的列数和可变的行数组成的逻辑结构。 列 是一组相同数据类型的值。 在 表 中 不必对行进行排序。 要 对结果集进行排序, 必 须在从表中选择数据的 SQL 语句中显式指 定 排序。在每个列和行的相交处是一个称为值的特定数据项。在图 1中, 'Sanders' 是表中值 的一个示例。 基表是用 CREATETABLE 语句创建的,用于保存用户数据。结果表 是一组行,数据 库管理程序从一个或多个基表选择或生成这组行以满足查询要求。 图1说明了表的一部分。列和行已标记。 图1. 表的可视化 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 3 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 视图 视图 视图 视图 视图提供了在一个或多个表中查看数据的替代方法。它是表上的一个动态窗口。 视图允许多个用户查看同一数据的不同表示。 例 如, 几 个用户可以同时存取一个关于 雇 员的数据表。 一 个用户可以查看关于某些雇员而非其他雇员的数据, 而 另一个用户可以查 看 关于所有雇员的某些数据而非他们的薪水。 这 些用户的每一个都在操作一个从该实表派生 的 视图。每个视图都显示为一个表并有自己的名称。 使用视图的优点是您可以使用它们来控制对敏感数据的存取。 所 以, 不 同的人可以存 取 数据的不同列或行。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 模式 模式 模式 模式 模式是命名对象的集合, 并 提供了数据库中对象的逻辑分类。 模 式可以包含数据库对 象, 如表和视图等。 模式本身也可以认为是数据库中的一个对象。 当 创建表或视图时隐式创建了模式。 或 者, 可以使用 CREATESCHEMA 语句显式创建它。 创建对象时, 可 以用特定模式的名称来限定对象的名称。 命 名对象有两部分名称, 其 中 第一部分名称是指定给对象的模式名。 如 果未指定模式名, 则 给对象指定其名称是用户执 行 语句的权限 ID 的缺省模式。 对 于交互式 SQL, 该 方法用于执行本书中的示例, 权 限 ID 为 用CONNECT 语句指定的用户 ID。 例 如, 如果表名为 STAFF,CONNECT 语句中指定 的 用户 ID 为USERID ,则 限 定 名 为 USERID.STAFF。参 见连接数据库以获取关于 CONNECT 语句的详情。 某些模式名是系统保 留的。例 如,当 预安装的 用户定义 函数 属于 SYSFUN 模式时, 内部函数处于 SYSIBM 模式。参考 SQL Reference 以获取关于 CREATESCHEMA 语句 的详情。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 数据 类型 数据 类型 数据 类型 数据 类型 Christen 整理:SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 4 数据类型定义常数、列、宿主变量、函数、表达式以及专用寄存器可接受的值。本节描 述示例中引用的数据类型。有关其他数据类型的完整列表和说明,参考 SQL Reference。 字符串 字符串为一个字节序列。字符串的长度为序列中的字节数。如果长度为零,则该字符串 的值称为空字符串。 定长字符串 CHAR(x)是定长字符串。长度属性 x 必须在 1 和 254 之间,并包括 1 和 254。 变长字符串 变长字符串有三种类型:VARCHAR、LONGVARCHAR 以及 CLOB。 VARCHAR(x) 类型是变长字符串,因此,可以将长度为 9 的字符串插入 VARCHAR(15)中,而该字符串 的长度将仍然为 9。参见大对象 (LOB)以获取关于 CLOB 的详情。 图形字符串 图形字符串是一个双字节字符数据序列。 定长图形字符串 GRAPHIC(x)是定长字符串。长度属性 x 必须在 1 和 127 之间,并包括 1 和 127。 变长图形字符串 变长图形字符串有三种类型: VARGRAPHIC、LONGVARGRAPHIC 以及 DBCLOB。 参见大对象 (LOB)以获取关于 DBCLOB 的详情。 二进制字符串 二进制字符串是一个字节序列。它用于保存非传统数据,如图象等。“二进制大对象” (BLOB) 是二进制字符串。参见大对象 (LOB)以了解更多信息。 数字 所有数字都有符号和精度。精度是除符号位以外的位数或数字数。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 5 SMALLINT SMALLINT(小型整数)是精度为 5 位的两字节整数。 INTEGER INTEGER(大型整数)是精度为 10 位的四字节整数。 REAL REAL(单精度浮点数)是实数的 32 位近似值。 DOUBLE DOUBLE(双精度浮点数)是实数的 64 位近似值。 DOUBLE 也称 FLOAT。 DECIMAL(p,s) DECIMAL 是一个十进制数。小数点的位置由数字的 精度 (p)和小数位 (s) 确定。精度 是数字的总位数,必须小于 32。小数位是小数部分数字的位数且总是小 于或等于精度值。 如果未指定精度和小数位,则十进制值的缺省精度为 5,缺省小数位为 0。 日期时间值 日期时间值是日期、 时 间以及时间戳记的表示。 日 期时间值可以用于某些算术运算和 字 符串运算并且与某些字符串是相容的,然而它们既非字符串也非数字。 (1) 日期 日期值分为三个部分(年、月以及日) 。 时间 时间是用 24 小时制式来指定一天内的时间的值, 分 为三个部分 ( 小时、 分 钟以及秒) 。 时间戳记 时间戳记为指定日期和时间的值, 分为七个部分 (年、 月、 日、 小时、 分钟、秒以及 微 秒)。 空值是一个区别于所有非空值的特殊值。 它 意味着行中的那一列无任何其他值。 所 有 数 据类型都存在空值。 下表突出显示示例中所使用的数据类型的特性。 所 有数字数据类型都定义在某一确定 范 围内。 该 数字数据类型范围也包括在此表中。 可 以使用此表作为正确数据类型用法的快速 参 考。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 6 有关更多信息,参见 SQL Reference 中的数据类型相容性创建表和视图 第二 部分 : 创建 表和 视图 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 创建 表 创建 表 创建 表 创建 表 使用 CREATETABLE 语句创建自己的表,指定列名和类型以及约束。 约束在 用约 束 和触发器实施商业规则 (点击查看 ) 中讨论。 下列 语 句 创 建 一个 命 名 为 PERS 的表 , 该 表 与 STAFF 表类 似 , 但 有 一个 附 加列 BIRTH_DATE。 CREATETABLEPERS (IDSMALLINTNOTNULL, NAME VARCHAR(9), DEPTSMALLINTWITHDEFAULT 10, JOB CHAR(5), Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 7 YEARSSMALLINT, SALARY DECIMAL(7,2), COMM DECIMAL(7,2), BIRTH_DATEDATE) 此语句创建一个其中无数据的表。下一节描述如何将数据插入新表。 如示例中所示, 为每一列都指定名称和数据类型。 数据类型在 数据类型 (点击查看 ) 中 讨论。 NOTNULL 是可选的,可以指定它以表示列中不允许有空值。缺省值也是可选的。 可以在 CREATETABLE 语句中指定许多其他选项,如唯一约束或 参考约束。有关所 有选项的详情,参见 SQL Reference 中的 CREATETABLE 语句。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 插入 数据 插入 数据 插入 数据 插入 数据 当创建新表时,新表不包含任何数据。要将新的行输入表中,使用 INSERT 语句。此 语句有两种一般格式: 一种格式, 使用 VALUES 子句来指定一行或多行的列值。 下面三个示例使用此一般 格 式将数据插入表中。 另一种格式, 指 定全查询而非指定 VALUES 来标识来自包含在其他表和/或视图中 的 行的列。 全查询是 INSERT 或CREATEVIEW 语句中所使用的选择语句、 或 者是跟在谓词后 面 的选择语句。括在括号中的全查询一般称为子查询。 根据创建表时已选择的缺省选项, 对 于每个插入的行, 为 每一列提供一个值或者接受 一 个缺省值。各种数据类型的缺省值在 SQL Reference 中讨论。 下列语句使用 VALUES 子句将一行数据插入 PERS 表中: INSERTINTOPERS VALUES(12, 'Harris', 20, 'Sales', 5, 18000, 1000, '1950-1-1') 下列语句使用 VALUES 子句将三行插入其中只有 ID、名称以及工作是已知的 PERS 表中。如 果列 定义 为 NOTNULL 且没有缺 省值 ,则 必须 为该 列指 定 一个 值。 CREATE TABLE 语句中的列定义上的 NOTNULL 子句可以用单词 WITHDEFAULT 扩 充 。 如果 某 一列定义为 NOTNULLWITHDEFAULT 或常数缺省值 ( 如 WITHDEFAULT 10) ,并 且 您 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 8 未在列列表中指定该列, 则 缺省值插入至已插入行的该列中。 例 如, 在 CREATETABLE 语 句中, 仅 为 DEPT 列指定了缺省值并将该值定义为 10。因此 , DEPT 设置为 10 而所有 其 他列都为空。 INSERTINTOPERS(NAME,JOB,ID) VALUES('Swagerman', 'Prgmr', 500), ('Limoges', 'Prgmr', 510), ('Li', 'Prgmr', 520) 下列语句返回插入的结果: SELECT* FROMPERS 注意: 在此情况下, 并未给每个列指定值。空值显示为 -。 为此, 列名列表的次序和 数 据类型都必须与 VALUES 子句中提供的值对应 。如果省 略列名 列表(如 第一个示 例中那 样),则VALUES 之后的数据值列表的次序必须与它们所插入至的表中的列次序相同,值 的数目必须等于表中列的数目。 每个值必须与它所插入至的列的数据类型相容。 如 果某列定义为可空, 且 未指定该列 的 值,则将空值赋给插入行中的该列。 下列示例将空值插入 YEARS、COMM 和BIRTH_DATE 中,因为未给行中的那些列 指定值。 INSERTINTOPERS(ID,NAME,JOB,DEPT,SALARY) VALUES(410, 'Perna', 'Sales', 20, 20000) INSERT 语句的第二种格式对于用来 自另一表中 行的值填充 表非常方便 。如所述的那 样,指定全查询而非指定 VALUES 以标识来自包含在其他表和/或视图中的行中的列。 下列示例从员工 STAFF 表中选择部门 38 的成员的数据,并将它插入 PERS 表中: INSERTINTOPERS(ID,NAME,DEPT,JOB,YEARS,SALARY) Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 9 SELECTID,NAME,DEPT,JOB,YEARS,SALARY FROMSTAFF WHEREDEPT = 38 在此插入之后,下列 SELECT 语句与 INSERT 语句中全查询产生的结果相同。 SELECTID,NAME,DEPT,JOB,YEARS,SALARY FROMPERS WHEREDEPT = 38 结果为: 表。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 更改 数据 更改 数据 更改 数据 更改 数据 使用 UPDATE 语句来更改表中的数据。使用此语句,可以更改满足 WHERE 子句搜 索条件的每行中的一列或多列的值。 下列示例更新其 ID 为410 的雇员的信息: UPDATEPERS SET JOB='Prgmr', SALARY = SALARY + 300 WHEREID = 410 SET 子句指定要更新的列并提供值。 WHERE 子句是可选的,它指定要更新的行。如果省略 WHERE 子句,则数据库管 理 程序用您提供的值更新表或视图中的每一行。 在此示例中,首先命名表 (PERS),然后指定要更新行的条件。雇员编号 410 的信息 已更改:该雇员的工作职位更改为 Prgmr,它的薪水增加了 300$。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 10 可以通过包括应用于两行或更多行的 WHERE 子句来更改多行数据。下列示例给每个 销售员的薪水增加 15%: UPDATEPERS SETSALARY = SALARY* 1.15 WHEREJOB = 'Sales' SQL SQL SQL SQL 入门入门入门 入门 ::: : 删除数据删除数据删除数据 删除数据 使用 DELETE 语句,基于在 WHERE 子句中指定的搜索条件从表中删除数据行。下 列示例删除其中雇员 ID 为120 的行: DELETEPERS WHEREID = 120 WHERE 子句是可选的,它指定要删除的行。如果省略 WHERE 子句,则数据库管 理 程序删除表或视图中的所有行。 可以使用 DELETE 语句删除多行。 下 列示例删除其中雇员部门 (DEPT) 为20 的所 有 行: DELETEPERS WHEREDEPT = 20 当删除某一行时,是除去整行,而不是除去行中的特定列值。 要删除表的定义及其内容,发出 DROPTABLE 语句,如 SQL Reference 中所述。 SQL SQL SQL SQL 入门入门入门 入门 ::: : 创建视图创建视图创建视图 创建视图 如视图中所讨论的,视图提供在一个或多个表中查看数据的替代方法。通过创建视图, 可以对想要各种用户查看的信息进行限制。下列图表显示视图和表之间的关系。 图2. 表和视图之间的关系 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 11 在图 2中, View_A 被限制仅存取 TABLE_A 的列 AC1 和AC2。View_AB 允许存 取TABLE_A 中的列 AC3 和TABLE_B 中的列 BC2 。通过创建 View_A,将用户可以具 有的存取权限制于 TABLE_A, 通 过创建 VIEW_AB, 将 存取权限制于某些列并创建查看 数 据的替代方式。 下列语句创建 STAFF 表中20 部门的非经理人员视图,其中薪水和佣金不通过基表 显示。 CREATEVIEWSTAFF_ONLY ASSELECTID,NAME,DEPT,JOB,YEARS FROMSTAFF WHEREJOB <> 'Mgr' AND DEPT=20 在创建视图之后,下列语句显示视图的内容: SELECT* FROMSTAFF_ONLY Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 12 此语句产生下列结果: 早 些 时 候 , 我们 把 STAFF 和ORG 表连接起来产生一个列出每个部门名称及其部门 经 理姓名的结果。下列语句创建可重复用于相同目的的视图: CREATEVIEWDEPARTMENT_MGRS ASSELECTNAME,DEPTNAME FROMSTAFF,ORG WHEREMANAGER = ID 创建视图时,可以使用 WITHCHECKOPTION 子句将附加约束添加到通过视图插入 和更新表。此子句导致数据 库管理程序 验证对视图 的任何更新 或插入是否 符合该视图 的定 义, 并 拒绝那些不符合定义的更新或插入。 如 果省略此子句, 则 不检查违反视图定义的插 入 和更 新 。 有 关 WITHCHECKOPTION 如何 起作用的详情,参考SQL Reference 中的 CREATEVIEW 语句。 使用视图来处理数据 象SELECT 语句一样, INSERT、DELETE 以及 UPDATE 语句可以应用于视图,就 好象视图是一个实表一样。 这 些语句处理基本基表中的数据。 因 此当再次存取该视图时, 使 用最新的基表对它进行计算。 如果未使用 WITHCHECKOPTION, 则使用视图修改的数 据 可能由于不再满足原始视图定义而不在视图的重复存取中出现。 下列是一个将更新应用于视图 FIXED_INCOME 的示例: FIXED_INCOME 的视图定义: CREATEVIEWFIXED_INCOME(LNAME,DEPART,JOBTITLE,NEWSALARY) ASSELECTNAME,DEPT,JOB,SALARY FROMPERS WHEREJOB <> 'Sales' WITHCHECKOPTION UPDATEFIXED_INCOME Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 13 SETNEWSALARY = 19000 WHERELNAME = 'Li' 除了校验选项以外,先前视图中的更新等效于对基表 PERS 的更新: UPDATEPERS SETSALARY = SALARY* 1.10 WHERENAME = 'Li' ANDJOB <> 'Sales' 注意:由 于 视图 是在 CREATEVIEWFIXED_INCOME 中对约束 JOB <> 'Sales'使用 WITHCHECKOPTION 创建的,所以当 Limoges 调去做销售时不允许下列更新: UPDATEFIXED_INCOME SETJOBTITLE = 'Sales' WHERELNAME = 'Limoges' 不能更新由表达式 SALARY + COMM or SALARY* 1.25 定义的列。如果定义的视图 包含一列或多个这样的列,则拥有者不接受对这些列的更新 (UPDATE)特权。在包含这样的 列的视图上不允许 INSERT 语句,但允许 DELETE 语句。 考虑一个没有一列定义为 NOTNULL 的PERS 表。 可 以通过 FIXED_INCOME 视图 将行 插 入 PERS 表中 ,即使该视图不包含基本表PERS 的ID、YEARS、COMM 或 BIRTHDATE。整个视图中看不到的列被适当地设置为空值或缺省值。 然而, PERS 表确实已将列 ID 定义为 NOTNULL。如果尝试通过 FIXED_INCOME 视图插入行, 则 系统试图将空值插入在整个视图中 “看不到 ”的所有 PERS 列 。 由于 ID 列 未包括在视图中并且该列不允许空值,所以系统不允许通过该视图进行插入。 有关修改视图的规则和限制,参考 SQL Reference 中的 CREATEVIEW 语句。 第三 部分 : 使用 SQLSQLSQL SQL 语句 存取 数据 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 选择 列 选择 列 选择 列 选择 列 使用 SELECT 语句从表中选择特定的列。 在该语句中指定用逗号分隔的列名列表。 此 列表称为选择列表。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 14 下列语 句 从 SAMPLE 数据库 的 ORG 表中选 择 部门 名 称 (DEPTNAME) 和部门号 (DEPTNUMB): SELECTDEPTNAME,DEPTNUMB FROMORG 上面语句产生下列结果: 通过使用星号 (*) 可从表中选择所有列。 下 一个示例列出 ORG 表中的所有的列和行 : SELECT* FROMORG 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 15 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 选择 行 选择 行 选择 行 选择 行 要从表中选择特定行,在 SELECT 语句之后使用 WHERE 子句指定要选择的行必须 满足的条件。从表中选择行的标准是搜索条件。 搜索条件由一个或多个谓词组成。谓词指定关于某一行是真或是假(或未知)的条件。 可使用下列基本谓词在 WHERE 子句中指定条件: 在构造搜索条件时, 要 注意只对数字数据类型执行算术运算, 并 只在相容数据类型之 间 进行比较。例如,不能将字符串与数字进行比较。 如果正在基 于字 符值 来选 择行 ,则该 值必 须用 单引 号括 起来 (例 如, WHEREJOB = 'Clerk') , 并且输入的每个字符值必须与数据库 中的完全一样。如 果数据值在数据 库中是小 写的, 而 您用大写形式来输入它, 则将不选择行。 如 果正在基于数字值来选择行, 则该值 不 得用引号括起来(例如, WHEREDEPT = 20)。 下列示例只从 STAFF 表中选择部门 20 的行: SELECTDEPT,NAME,JOB FROMSTAFF WHEREDEPT = 20 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 16 下一示例使用 AND 来指定多个条件。 可 以指定任意多个条件。 该 示例从 STAFF 表中 选择部门 20 中的 clerk: SELECTDEPT,NAME,JOB FROMSTAFF WHEREJOB = 'Clerk' ANDDEPT = 20 此语句产生下列结果: 未在其中输入值且不支持缺省值的列中出现空值。 将 值特别设置为空值的地方也可以 出 现空值。空值只能在定义为支持空值的列中出现。在表中定义和支持空值在创建表中讨论。 使用谓词 ISNULL 和ISNOTNULL 来检查空值。 下列语句列出佣金未知的雇员: SELECTID,NAME FROMSTAFF WHERECOMMISNULL 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 17 值零与空值不相同。下列语句选择表中佣金为零的每个人: SELECTID,NAME FROMSTAFF WHERECOMM = 0 因为样本表中的 COMM 列中没有零值,所以返回的结果集为空。 下一个示例选择 STAFF 表中 YEARS 的值大于 9 的所有行: SELECTNAME,SALARY,YEARS FROMSTAFF WHEREYEARS > 9 此语句产生下列结果: SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 将行 进行 排序 将行 进行 排序 将行 进行 排序 将行 进行 排序 您可能想要信息按特定次序返回。 使 用 ORDERBY 子句将信息按一个或多个列中 的 值进行排序。 下列语句显示部门 84 中按雇用年数排序的雇员: SELECTNAME,JOB,YEARS FROMSTAFF WHEREDEPT = 84 ORDERBYYEARS 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 18 指定 ORDERBY 作为整个 SELECT 语句中的最后一个子句。 在 此子句中命名的列 可 以是表达式或表的任何列。 ORDERBY 子句中的列名不必在选择列表中指定。 可通过在 ORDERBY 子句中显式指定 ASC 或DESC 将行按升序或降序进 行排序。 如果既未指定 ASC,也未指定 DESC,则自动按升序将行进行排序。下列语句按雇用年数 以降序显示部门 84 中的雇员: SELECTNAME,JOB,YEARS FROMSTAFF WHEREDEPT = 84 ORDERBYYEARSDESC 此语句产生下列结果: 可以按字符值以及数字值将 行进行排序 。下列语句 按姓名字母 顺序显示部 门 84 的雇 员: SELECTNAME,JOB,YEARS FROMSTAFF WHEREDEPT = 84 ORDERBYNAME 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 19 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 除去 重复 行 除去 重复 行 除去 重复 行 除去 重复 行 当使用 SELECT 语句时, 您 可能不想要返回重复信息。 例 如, STAFF 有一个其中 多 次列 出了几个部门编号的DEPT 列, 以及一个其中多次列出了几个工作说明的 JOB 列。 要消除重复行,在SELECT 子句上使用 DISTINCT 选 项 。 例如 , 如果 将 DISTINCT 插 入该语句,则部门中的每项工作仅列出一次: SELECTDISTINCTDEPT,JOB FROMSTAFF WHEREDEPT < 30 ORDERBYDEPT,JOB 此语句产生下列结果: DISTINCT 已消除了在 SELECT 语句中指定的一组列中所有包含重复数据的行。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 运算 次序 运算 次序 运算 次序 运算 次序 考虑运算次序是很重要的。 一 个子句的输出是下一个子句的输入, 如 下面列表中所 示。 给表达式命名 中给出一个要考虑其中运算次序的示例。 并且注意, 此 说明允许以一种更直观的方式对查询进行考虑。 此 说明不一定是在内部 执 行运算的方式。运算顺序如下: 1、FROM 子句 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 20 2、WHERE 子句 3、GROUPBY 子句 4、HAVING 子句 5、SELECT 子句 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 使用 表达 式来计 算值 使用 表达 式来计 算值 使用 表达 式来计 算值 使用 表达 式来计 算值 表达式是包括在语句中的计算或函数。 下 列语句计算, 如 果部门 38 中每个雇员都 收 到$500 的奖金,则每人的薪水将是多少: SELECTDEPT,NAME,SALARY + 500 FROMSTAFF WHEREDEPT = 38 ORDERBY 3 此结果为: 注意第三列的列名是一个数字。 这 是一个系统生成的数字, 因 为 SALARY+500 未指 定 列名。以后此数字在 ORDERBY 子句中用来表示第三列。 给表达式命名 (点击查看 ) 论及 如何给表达式取有意义的名称。 可使用基本算术运算符加 (+)、减 (-)、乘 (*)、除 (/)来形成算术表达式。 这些运算符可对几种不同类型操作数的值进行运算,其中某些操作数为: 列名(例如在 RATE*HOURS 中) 常数值(例如在 RATE*1.07 中) Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 21 标量函数(例如在 LENGTH(NAME) + 1 中)。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 给表 达式 命名 给表 达式 命名 给表 达式 命名 给表 达式 命名 可选的 AS 子句允许您给表达式指定有意义的名称, 这 就使得以后再引用该表达式 更 容易。可使用 AS 子句为选择列表中的任何项提供名称。 下列语句显示其薪水加佣金少于 $13,000 的所有雇员。表达式 SALARY + COMM 命 名为 PAY: 此语句产生下列结果: 通过使用 AS 子句,可以在 ORDERBY 子句中引用特定的列名而不是系统生成的数 字。 在此示例中, 我 们在 WHERE 子句中将 (SALARY + COMM)与13000 进行比较, 而 不 是使用名称 PAY。这是运算次序的结 果。在将 (SALARY + COMM)命名为 PAY 之前计算 WHERE 子句的值。因此,不能在该谓词中使用 PAY。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 从多 个表 中选择 数据 从多 个表 中选择 数据 从多 个表 中选择 数据 从多 个表 中选择 数据 可使用 SELECT 语句从两个或多个表中生成包含信息的报告。 这 通常称为 连接。 例 如 , 可以 连 接 STAFF 和ORG 表中的数据以形成一个新表。 要 连接两个表, 在 SELECT 子句中指定想要显示的列, 在 FROM 子句中指定表名,在 WHERE 子句中指定搜索 条件。 WHERE 子句是可选的。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 22 下一个示例使每个经理的姓名与部门名称关联。 需 要从两个表中选择信息, 因 为雇员 信 息(STAFF 表) 和 部门信息 ( ORG 表) 是 独立存储的。 下 列查询分别选择 STAFF 和ORG 表的 NAME 和DEPTNAME 列。 搜 索条件将选择范围缩小为 MANAGER 列中的值与 ID 列中的值相同的行: SELECTDEPTNAME,NAME FROMORG,STAFF WHEREMANAGER = ID 图3演示如何比较两个不同表中的列。加框线的值表示满足搜索条件的匹配项。 图3. 从STAFF 和ORG 表中选择 SELECT 语句产生下列结果: 该结果列出每个经理的姓名和他或她的部门。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 23 SQL SQL SQL SQL 入门入门入门 入门 ::: : 使用子查询使用子查询使用子查询 使用子查询 在编写 SELECT 语句时, 可 在 WHERE 子句中放置另一个 SELECT 语句。 每 个附 加 的SELECT 启动一个子查询。 子查询本身又可包括其值代入其 WHERE 子句的另一个子查询。另外, WHERE 子句 可将子查询包括在多个搜索条件中。子查询可引用与主查询中所使用的不同的表和列。 下列语句从 ORG 表中选择 STAFF 表中其 ID 为280 的雇员的分部和位置: 在处理此语句时, DB2 首先确定子查询的结果。结果为 66,因为具有 ID 280 的雇 员 在部门 66。则最终结果从其部门号列具有值 66 的ORG 表的行中得出。最终结果是: 当使用子查询时,数据库管理程序计算该子查询并将结果值直接代入 WHERE 子句。 SQL SQL SQL SQL 入门入门入门 入门 ::: : 使用函数使用函数使用函数 使用函数 本节简要介绍了将用于全书示例的函数。 数据库函数是一组输入数据值和一个结果 值之间的关系。 函数可以是内部的或用户定义的。 DB2 通用数据库提供很多内部函数和预安装的用 户 定义函数。可找到 SYSIBM 模式的内部函数和 SYSFUN 模式的预安装的用户定义函 数。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 24 SYSIBM 和SYSFUN 是保留模式。 内部函数和预安装的用户定义函数从不会满足所有需求。 所 以应用程序开发者可能需 要 创建自己的一套特定于他们的应用程序的函数。 用 户定义函数使这成为可能, 例 如通过扩 展 DB2 通用数据库的范围以包括定制的商业或科学函数。这在用户定义函数中进一步讨论。 列函数 列函数对列中的一组值进行运算以得到单个结果值。 下 列就是一些列函数的示例。 有 关 完整列表,参考 SQL Reference。 AVG 返回某一组中的值除以该组中值的个数的和 COUNT 返回一组行或值中行或值的个数 MAX 返回一组值中的最大值 MIN 返回一组值中的最小值 下列语句从 STAFF 表中选择最高薪水: SELECTMAX(SALARY) FROMSTAFF 此语句从员工 STAFF 样本表中返回值 22959.20。 下一个示例选择其收入超过平均收入但在公司的年数少于平均年数的雇员姓名和薪水。 SELECTNAME,SALARY FROMSTAFF WHERESALARY > (SELECTAVG(SALARY)FROMSTAFF) ANDYEARS < (SELECTAVG(YEARS)FROMSTAFF) 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 25 在上面示例中的WHERE 子句中,与直接实现列函数(WHERESALARY > AVG(SALARY)) 相反, 在 子查询中说明列函数。 不 能在 WHERE 子句中说明列函数。 这 是 由于运算次序的 结果。 可认为 WHERE 子句是在 SELECT 子句之前进行计 算的。 因此, 当正在计算 WHERE 子句时,列函数没有对该组值的存取权。 稍后由 SELECT 子句选择 这组值。 可指定 DISTINCT 作为列函数自变量的一部分, 以 在应用函数之前消除重复值。 因 此, COUNT(DISTINCTWORKDEPT) 计算不同部门的个数。 标量函数 标量函数对值进行某个运算以返回另一个值。下列就是一些由 DB2 通用数据库提供的 标量函数的示例。 ABS 返回数的绝对值 HEX 返回值的十六进制表示 LENGTH 返回自变量中的字节数(对于图形字符串则返回双字节字符数。 ) YEAR 抽取日期时间值的年份部分 有关标量函数的详细列表和说明,参考 SQL Reference。 下列语句返回 ORG 表中的部门名称以及其每个名称的长度: SELECTDEPTNAME,LENGTH(DEPTNAME) FROMORG 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 26 注意:由于未使用 AS 子句给 LENGTH(DEPTNAME) 取一个有意义的名称,所以第 二列中出现系统生成的数字。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 用户 定义 函数 用户 定义 函数 用户 定义 函数 用户 定义 函数 如使用函数中 所述, DB2 通用数据库提供内部函数和 用户定义函 数 (UDF)。然而, 此函数集从不会满足所有需求。 您常常需要为特别的任务创建定制函数。 用户定义函 数 允许您创建定制函数。 用户定义函数有两种类型:源和外部函数。 源用户定义函数允许允许用 户定义类型 有选择地引 用另一个已 为数据库所 知的内部函 数或用户定义函数。您可以既使用标量函数又使用列函数。 在下一示例中, 基于内 部 MAX 列函数来创建称 为 MAX 的用户定义函数 ,它采用 DECIMAL 数据类型作为输入。 MAXUDF 采用 PAY 类型作为输入且返回一个 PAY 类型 作为输出。 CREATEFUNCTIONMAX(PAY)RETURNSPAY SOURCEMAX(DECIMAL) 外部用户定义函数由用户用程序设计语言编写。 有 外部标量函数和外部表函数, 在 SQL Reference 中讨论了这两个函数。 假定您已编写 了一 个计算 字符 串中字 数的 函数, 则您 可以使 用 CREATEFUNCTION 语句以名称 WORDCOUNT 向数据库注册该函数。然后就可在 SQL 语句中使用此函数。 例如,下列语句返回雇员编号和他们简历的 ASCII 格式的字数。 WORDCOUNT 是用 户已向数据库注册并且现正在语句中使用的外部标量函数。 SELECTEMPNO,WORDCOUNT(RESUME) FROMEMP_RESUME WHERERESUME_FORMAT = 'ascii' Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 27 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 分组 分组 分组 分组 I、分组 DB2 通用数据库具有基于表的特定列对数据进行分析的能力。 可按照在 GROUPBY 子句中定义的组对行进行分组。 以 其最简单的形式, 组 由称为 分 组列的列组成。 SELECT 子句中的列名必须为分组列或列函数。列 函数对于 GROUPBY 子句定义的每个组各返回一 个结果。下 列示例产生 一个列出每 个部门编号 的最高薪水 的结 果: SELECTDEPT,MAX(SALARY)ASMAXIMUM FROMSTAFF GROUPBYDEPT 此语句产生下列结果: 注意 :计算的是每个部门(由GROUPBY 子句 定义的组)而不是整个公司的 MAX(SALARY)。 II、将 WHERE 子句与 GROUPBY 子句一起使用 分组查询可以在形成组和计算列函数之前具有消除非限定行的标准 WHERE 子句。必 须在 GROUPBY 子句之前指定 WHERE 子句。例如: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 28 SELECTWORKDEPT,EDLEVEL,MAX(SALARY)ASMAXIMUM FROMEMPLOYEE WHEREHIREDATE > '1979-01-01' GROUPBYWORKDEPT,EDLEVEL ORDERBYWORKDEPT,EDLEVEL 结果为: 注意: 在 SELECT 语句中指定的每个列名也在 GROUPBY 子句中提到。 未在这两 个 地方提到的列名将产生错误。 GROUPBY 子句对 WORKDEPT 和EDLEVEL 的每个唯一 组合各返回一行。 III、在 GROUPBY 子句之后使用 HAVING 子句 可应用限定条件进行分组, 以 便系统仅对满足条件的组返回结果。 为 此, 在 GROUPBY 子句后面包含一个 HAVING 子句。HAVING 子句可包含一个或多个用 AND 和OR 连接 的谓词。每个谓词将组特性(如 AVG(SALARY))与下列之一进行比较: 该组的另一个特性 例如: HAVINGAVG(SALARY) > 2 *MIN(SALARY) 常数 例如: HAVINGAVG(SALARY) > 20000 例如,下列查询寻找雇员数超过 4 的部门的最高和最低薪水: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 29 SELECTWORKDEPT,MAX(SALARY)ASMAXIMUM,MIN(SALARY)ASMINIMUM FROMEMPLOYEE GROUPBYWORKDEPT HAVINGCOUNT(*) > 4 ORDERBYWORKDEPT 此语句产生下列结果: 有可能(虽然很少见)查询有 HAVING 子句但没有 GROUPBY 子句。在此情况下, DB2 将整个表看作一个组。因为该表被看作是单个组,所以最多可以有一个结果行。如果 HAVING 条件对整个表为真, 则返回选择的结果 (该结果必须整个由列函数组成) ; 否 则 不 返回任何行。 第四 部分 :表 达式 和子 查询 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 标量 全查 询 标量 全查 询 标量 全查 询 标量 全查 询 标量全查询是在括号中的全查询, 该 查询返回的一行只包含一个列值。 标 量全查询 对 从数据库中检索数据值供表达式使用是很有用的。 1、下列示例列出其薪水超过全部雇员平均薪水的雇员的姓名: SELECTLASTNAME,FIRSTNME FROMEMPLOYEE WHERESALARY > (SELECTAVG(SALARY) FROMEMPLOYEE) 2、下列示例在两个不同的表中查寻雇员的平均薪水: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 30 SELECTAVG(SALARY)AS"Average_Employee", (SELECTAVG(SALARY)AS"Average_Staff" FROMSTAFF) FROMEMPLOYEE SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 转换 数据 类型 转换 数据 类型 转换 数据 类型 转换 数据 类型 有时可能需要将一些值从一种数据类型转换成另一种数据类型, 例 如, 从 数字值转 换 成字符串。要将一个值转换成另一个不同的类型,使用 CAST 说明。 转换说明的另一个可能用途是截断很长的字符串。 在 EMP_RESUME 表中, RESUME 列是 CLOB(5K)。您 可能只想显示包含应聘者个人信息的前370 个字 符 。 要 从 EMP_RESUME 表中显示简历的 ASCII 格式的前 370 个字符,发出下列请求: SELECTEMPNO,CAST(RESUMEAS VARCHAR(370)) FROMEMP_RESUME WHERERESUME_FORMAT = 'ascii' 会发出一个警告,通知您超过 370 个字符的值被截断。 可将空值转换为更便于在查询中进行处理的其他数据类型。 公共表表达式 是一个为此 目的使用转换的示例。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 条件 表达 式 条件 表达 式 条件 表达 式 条件 表达 式 可在 SQL 语句中使用 CASE 表达式以便于处理表的数据表示。这提供了一种功能 强大的条件表达式能力,在概念上与某些程序设计语言中的 CASE 语句类似。 要从 ORG 表中的 DEPTNAME 列将部门编号更改为有意义的词,输入下列查询: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 31 结果为: 可使用 CASE 表达式来防止出现异常情况,如被零除等。在下列示例中,如果雇员没 有奖金或佣金报酬,则语句条件通过避免除法运算来防止出错: 可在单个语句中使用 CASE 表达式,根据一个列中值的子集的总和与该列中所有值的 总和的比来产生一个比率。使用 CASE 表达式的语句只需要传送数据一次。在没有 CASE 表达式的情况下,执行同样的计算至少需要传送两次。 下列示例使用 CASE 表达式计算部门 20 的薪水之和与全部薪水总额的比率: 结果为 0.11。注意: CAST 函数确保结果的精度得到保持。 可使用 CASE 表达式来计算简单的函数,而不必调用函数本身,调用函数将需要额外 开销。例如: 此表达式与 SYSFUN 模式中 SIGN 用户定义函数有相同的结果。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 32 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 表表 达式 表表 达式 表表 达式 表表 达式 1、表表达式 如果只需要单个查询的视图定义,可使用表表达式。 表表达式是临时的, 只 在 SQL 语句的使用期限内有效; 表 表达式不能共享, 但它们 比 视图更灵活。任何授权的用户都可共享视图定义。 本节描述如何在查询中使用公共表表达式和嵌套表表达式。 2、公共表表达式 公共表表达式是在全查询的开头使用 WITH 关键字定义的命名结果表。公共表表达 式 是您创建以在复杂查询之中使用的表表达式。在查询的开头使用 WITH 子句定义并命名 公 共表表达式。 对 公共表表达式的重复引用使用同一个结果集。 相 比之下, 如 果使用嵌套表 表 达式或视图,则每次都将重新生成结果集,其结果可能各不相同。 下列示例列出公司中教育级别大于 16、平均工资比那些同时雇用的且有同样教育级别 的人低的所有人。在该查询后面会更详细地描述查询的各个部分。 (1) WITH PAYLEVELAS (SELECTEMPNO,YEAR(HIREDATE)ASHIREYEAR,EDLEVEL, SALARY+BONUS+COMM ASTOTAL_PAY FROMEMPLOYEE WHEREEDLEVEL > 16), (2) PAYBYED(EDUC_LEVEL,YEAR_OF_HIRE, AVG_TOTAL_PAY)AS (SELECTEDLEVEL,HIREYEAR,AVG(TOTAL_PAY) FROMPAYLEVEL GROUPBYEDLEVEL,HIREYEAR) (3) Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 33 SELECTEMPNO,EDLEVEL, YEAR_OF_HIRE, TOTAL_PAY, DECIMAL(AVG_TOTAL_PAY,7,2) FROMPAYLEVEL,PAYBYED WHERE EDLEVEL=EDUC_ LEVEL ANDHIREYEAR = YEAR_OF_HIRE ANDTOTAL_PAY< AVG_TOTAL_PAY (1)这是名为 PAYLEVEL 的公共表表达式。此结果表包括雇用某个 人的年份、该雇员 的总收入以及他(或她)的教育级别。只包括雇员的教育级别大于 16 的那些行。 (2)这是名为 PAYBY ED(或 PAY by education) 的 公共表表达式。 该表达式使用在前 一 个公共表表达式中创建的 PAYLEVEL 表来确定每个教育级别同一 年雇用的雇 员的教育级 别、 雇 用年份以及平均收入。 此 表返回的列被赋予的名称与选择列表中所使用的列名不同 (如 EDUC_ LEVEL) 。 这会生成命名为 PAYBYED 的结果集,与嵌套表表达式示例中产生的结 果相同。 (3)最后, 我 们获得能产生期望结果的实际查询。 连 接这两个表 ( PAYLEVEL,PAYBY ED) 以确定总收入比同年雇用的人的平均收入低的那些人。注意: PAYBYED 是以 PAYLEVEL 为基础。 所 以在完整语句中有效地存取了 PAYLEVEL 两次。 两 次都使用同一组行来计算 查 询。 最终结果如下: 3、嵌套表表达式 嵌套表表达式是一个临时视图, 其 中的定义被嵌套 ( 直接定义) 在 主查询的 FROM子句 中。 下列查询使用嵌套表表达式来寻找那些教育级别超过 16 的雇员的平均总收入、 教 育 级 别以及雇用年份: SELECTEDLEVEL,HIREYEAR,DECIMAL(AVG(TOTAL_PAY), 7,2) FROM(SELECTYEAR(HIREDATE)ASHIREYEAR,EDLEVEL, SALARY+BONUS+COMM ASTOTAL_PAY FROMEMPLOYEE WHEREEDLEVEL > 16 )ASPAY_LEVEL GROUPBYEDLEVEL,HIREYEAR ORDERBYEDLEVEL,HIREYEAR Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 34 结果如下: SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 相关 名 相关 名 相关 名 相关 名 相关名 是 用 于 识别 一 个 对 象的 多 种 用 途的 标 识 符 。可 在 查 询 的 FROM 子句中和 UPDATE 或DELETE 语句的第一个子句中定义相关名。 相 关名可与表、 视图或嵌套 表 表达式关联,但只限于定义相关名的上下文中。 例如,子句 FROMSTAFFS、ORGO 分别指定 S 和O 作为 STAFF 和ORG 的相 关名。 SELECTNAME,DEPTNAME FROMSTAFFS,ORGO WHEREO.MANAGER = S.ID 一旦 定义了相关名,则只可以使用相关名来限定对象。例如,上例中如果写成 ORG.MANAGER=STAFF.ID 的话,则该语句就会失效。 也可以使用相关名作为表示数据库对象的简称。只输入 S 比输入 STAFF 更容易。 通过使用相关名, 可 复制对象。 这 在需要将表中各项与自己本身作比较时很有用。 在 下 列示例中, EMPLOYEE 表与它自己的另一个实例比较以寻找所有雇员的经理。 该 示例显 示 非设计员的雇员的姓名、这些雇员的经理的姓名以及部门编号。 SELECT E2.FIRSTNME, E2.LASTNAME, E2.JOB, E1.FIRSTNME, E1.LASTNAME, E1.WORKDEPT FROMEMPLOYEE E1, EMPLOYEE E2 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 35 WHERE E1.WORKDEPT = E2.WORKDEPT AND E1.JOB = 'MANAGER' AND E2.JOB <> 'MANAGER' AND E2.JOB <> 'DESIGNER' 此语句产生下列结果: 相关 子查 询 相关 子查 询 相关 子查 询 相关 子查 询 允许引用先前提到的任何表的子查询称为相关子查询。 我 们也说该子查询具有对主 查 询中表的相关引用。 下列示例是一个不相关子查询,该子查询 列出部门 'A00' 中薪水超过该部门平均薪水 的雇员的雇员编号和姓名: SELECTEMPNO,LASTNAME FROMEMPLOYEE WHEREWORKDEPT = 'A00' ANDSALARY > (SELECTAVG(SALARY) FROMEMPLOYEE WHEREWORKDEPT = 'A00') Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 36 如果想要知道每个部门的平均薪水, 则 需要对每个部门计算一次子查询。 对 在外层查 询 中标识的表的每一行,各使 用一次 SQL 的相关功能(该能力允许您 编写重复执 行的子查 询) , 就可做到这一点。此类型的相关子查询用来计算外层表的每一行的某个特性,该特性 是在子查询中计算谓词所需要的。 此示例显示薪水高于部门平均薪水的所有雇员: SELECT E1.EMPNO, E1.LASTNAME, E1.WORKDEPT FROMEMPLOYEE E1 WHERESALARY > (SELECTAVG(SALARY) FROMEMPLOYEE E2 WHERE E2.WORKDEPT = E1.WORKDEPT) ORDERBY E1.WORKDEPT 在此查询中,对每个部门计算一次子查询。结果为: 要编写带有相关子查询的查询, 使 用与带有子查询的普通外部查询相同的基本格式。 然 而, 在外部查询的 FROM 子句中, 只是在表名后面放置一个相关名。 于是子查询可能包 含 由该相关名限定的列引用。 例 如, 如 果 E1 是相关名, 则 E1.WORKDEPT 表示外部查询 中 表的当前行的工作部门值。在外部查询中对表的每一行(概念上)重新计算子查询。 通过使用相关子查询,可以使系统为您工作并减少需要在应用程序中编写的代码量。 DB2 中允许非限定相关引用。例 如,表 EMPLOYEE 有一个命名为 LASTNAME 的 列,表 SALES 有一个命名为 SALES_PERSON 的列,但没有命名为 LASTNAME 的列。 SELECTLASTNAME,FIRSTNME,COMM FROMEMPLOYEE Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 37 WHERE 3 > (SELECTAVG(SALES) FROMSALES WHERELASTNAME = SALES_PERSON) 在此示例中,系统检查最内层的 FROM 子句,以获取 LASTNAME 列。如果未找到 LASTNAME 列, 则 系统检查次最内层的 FROM 子句 ( 此情况下为外部 FROM 子句)。虽 然不总是必要的,还是建议限定相关引用以改进查询的可读性并确保获取想要的结果。 实现相关子查询 想何时使用相关子查询?列函数的使用有时是一条线索。 假定您想要列出教育级别高于部门平均值的雇员。 首先, 您 必须确定选择列表项。 问 题为 "List the employees"。 这隐 含 着 来 自 EMPLOYEE 表中 的 EMPNO 应该 足以唯一标识雇员。该问题也将EDLEVEL 和雇 员 的 部 门 WORKDEPT 说明为条件。 当 问题未明确要求显示列时, 在 选择列表中包括这些列将会有 助 于说明解法。现在可构造查询的一部分: SELECTLASTNAME,WORKDEPT,EDLEVEL FROMEMPLOYEE 接着需要搜索条件 ( WHERE子 句 ) 。 问题 语 句 为 "...whose level of education is higher than the average for that employee's department"。这意味着对于表中每个雇员,必须计算该雇员 所 在部门的平均教育级别。 此 语句适合相关子查询的说明。 正 在对每行计算某个特性 ( 当前 雇 员所在部门的平均教育级别) 。 EMPLOYEE 表需要相关名: SELECTLASTNAME,WORKDEPT,EDLEVEL FROMEMPLOYEE E1 需要的子查询较简单。该子查询计算每个部门的平均教育级别。完整的 SQL 语句为: SELECTLASTNAME,WORKDEPT,EDLEVEL FROMEMPLOYEE E1 WHEREEDLEVEL > (SELECTAVG(EDLEVEL) FROMEMPLOYEE E2 WHERE E2.WORKDEPT = E1.WORKDEPT) 结果为: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 38 假定不列出雇员的部门编号,则应列出部 门名称。需要的信 息 (DEPTNAME)在独立表 (DEPARTMENT)中。定义相关变量的外层查询也可以是连接查询 。 当在外层查询中使用连接时, 列 出要在 FROM 子句中连接的表, 并 将相关名放在这 些 表名的任何一个表名旁边。 要修 改 查 询 以 列出 部 门 名 称 而 不 是 部 门 编 号 , 在 选择 列 表 中 用 DEPTNAME 替换 WORKDEPT。FROM 子句现在也必须包括 DEPARTMENT 表,并且 WHERE 子句必须 表示适当的连接条件。 以下是修改的查询: SELECTLASTNAME,DEPTNAME,EDLEVEL FROMEMPLOYEE E1, DEPARTMENT WHERE E1.WORKDEPT = DEPARTMENT.DEPTNO ANDEDLEVEL > (SELECTAVG(EDLEVEL) FROMEMPLOYEE E2 WHERE E2.WORKDEPT = E1.WORKDEPT) 上例显示, 必 须在包含相关子查询的某个查询的 FROM 子句中定义用于子查询中的 相 关名。然而,这种包含可能涉及若干层嵌套。 假定某些部门只有几个雇员,因此这些部门的平均教育级别可能是错误的。可以决定, 为了使平均教育级别在用于比较雇员时是有意义的数字, 一 个部门中必须至少有 5 个雇员 。 因此现在必须列出教育级别高于雇员所在部门平均值的雇员,并只考虑至少有 5 个雇员的 部门。 该问题暗含另一个子查询, 因 为对于外层查询中每个雇员来说, 必 须计算该雇员所在 部 门的雇员总数: SELECTCOUNT(*) Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 39 FROMEMPLOYEE E3 WHERE E3.WORKDEPT = E1.WORKDEPT 仅当计数大于或等于 5 时才计算平均值: SELECTAVG(EDLEVEL) FROMEMPLOYEE E2 WHERE E2.WORKDEPT = E1.WORKDEPT AND 5 <= (SELECTCOUNT(*) FROMEMPLOYEE E3 WHERE E3.WORKDEPT = E1.WORKDEPT) 最后,只包括其教育级别高于部门平均值的那些雇员: SELECTLASTNAME,DEPTNAME,EDLEVEL FROMEMPLOYEE E1, DEPARTMENT WHERE E1.WORKDEPT = DEPARTMENT.DEPTNO ANDEDLEVEL > (SELECTAVG(EDLEVEL) FROMEMPLOYEE E2 WHERE E2.WORKDEPT = E1.WORKDEPT AND 5 <= (SELECTCOUNT(*) FROMEMPLOYEE E3 WHERE E3.WORKDEPT = E1.WORKDEPT)) 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 40 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 用集 合运 算符组 合查 询 用集 合运 算符组 合查 询 用集 合运 算符组 合查 询 用集 合运 算符组 合查 询 1、用集合运算符组合查询 UNION、EXCEPT 以及 INTERSECT 集合运算符使您能够将两个或更多外层查询组 合 成单个查询。 执 行用这些集合运算符连接的每个查询并组合各个查询的结果。 根 据运算符 不 同,产生不同的结果。 2、UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和TABLE2)并消去表中任 何重复行而派生出一个结果表。当 ALL 随UNION 一起使用时(即 UNIONALL),不消 除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。 在下列 UNION 运算符的示例中, 查 询返回薪水高于 $21,000、 有 管理责任且工龄少 于 8 年的人员的姓名: (1) SELECTID,NAMEFROMSTAFFWHERESALARY > 21000 UNION (2) SELECTID,NAMEFROMSTAFFWHERE JOB='Mgr' ANDYEARS < 8 ORDERBYID 各个查询的结果如下: (1) (2) Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 41 数据库管理程序组合这两个查询的结果,消除重复行,并按升序返回最终结果。 如果在带有任何集合运算符的查询中使用 ORDERBY 子句, 则 必须在最后一个查询 之 后写该子句。 系 统对组合的回答集进行排序。 如 果两个表中的列名不同, 则 组合的结果表 没 有相应列的名称。 替 代地, 将这些列按其出现的顺序编号。 因 此, 如果想要对结果表进行 排 序,则必须在 ORDERBY 子句中指定列号。 3、EXCEPT 运算符 EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复 行而派生出一个结果表。 当 ALL 随EXCEPT 一起使用时 (EXCEPTALL), 不 消除重复 行。 在下列 EXCEPT 运算符的示例中, 查 询返回收入超过 $21,000 但没有经理职位且工 龄 为8 年或更长的所有人员的姓名。 SELECTID,NAMEFROMSTAFFWHERESALARY > 21000 EXCEPT SELECTID,NAMEFROMSTAFFWHERE JOB='Mgr' ANDYEARS < 8 各个查询的结果在关于 UNION 的一节中列出。上面的语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 42 4、INTERSECT 运算符 INTERSECT 运算符通过只包括 TABLE1 和TABLE2 中都有的行并消除所 有重复行 而派生出一个结果表。 当 ALL 随INTERSECT 一起使用时 (INTERSECTALL), 不 消除 重 复行。 在下列 INTERSECT 运算符的示例中, 查询返回收入超过 $21,000 有管理责任且工 龄 少于 8年的雇员的姓名和 ID。 SELECTID,NAMEFROMSTAFFWHERESALARY > 21000 INTERSECT SELECTID,NAMEFROMSTAFFWHERE JOB='Mgr' ANDYEARS < 8 各个查询的结果在关于 UNION 的一节中列出。 这两个使用 INTERSECT 的查询的 结 果为: 5、当使用 UNION、EXCEPT 以及 INTERSECT 运算符时,记住下列事项: 运算 符的 查 询 选 择 列 表 中的 所 有 对 应 项 必须 是 相 容 的 。 有 关更 多 信 息 , 参 见 SQL Reference 中的数据类型相容性表。 ORDERBY 子句(如果使用该子句的话)必须放在最后一个带有集合运算符的查询后 面。 对 于每个运算符来说, 如 果列的名称与查询的选择列表中对应项的名称相同, 则 该列 名 只能在 ORDERBY 子句中使用。 在具有相同数据类型和相同 长度的列之 间进行的运 算会产生一 个具有该类 型和长度的 列 。 针对 UNION、EXCEPT 以及 INTERSECT 集合运算符的结果, 参 见 SQL Reference 中 结果数据类型的规则。 第五 部分 : 在查 询中 使用 运算 符和谓 词 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 43 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 用集 合运 算符组 合查 询 用集 合运 算符组 合查 询 用集 合运 算符组 合查 询 用集 合运 算符组 合查 询 1、用集合运算符组合查询 UNION、EXCEPT 以及 INTERSECT 集合运算符使您能够将两个或更多外层查询组 合 成单个查询。 执 行用这些集合运算符连接的每个查询并组合各个查询的结果。 根 据运算符 不 同,产生不同的结果。 2、UNION 运算符 UNION 运算符通过组合其他两个结果表(例如 TABLE1 和TABLE2)并消去表中任 何重复行而派生出一个结果表。当 ALL 随UNION 一起使用时(即 UNIONALL),不消 除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。 在下列 UNION 运算符的示例中, 查 询返回薪水高于 $21,000、 有 管理责任且工龄少 于 8 年的人员的姓名: (1) SELECTID,NAMEFROMSTAFFWHERESALARY > 21000 UNION (2) SELECTID,NAMEFROMSTAFFWHERE JOB='Mgr' ANDYEARS < 8 ORDERBYID 各个查询的结果如下: (1) (2) Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 44 数据库管理程序组合这两个查询的结果,消除重复行,并按升序返回最终结果。 如果在带有任何集合运算符的查询中使用 ORDERBY 子句, 则 必须在最后一个查询 之 后写该子句。 系 统对组合的回答集进行排序。 如 果两个表中的列名不同, 则 组合的结果表 没 有相应列的名称。 替 代地, 将这些列按其出现的顺序编号。 因 此, 如果想要对结果表进行 排 序,则必须在 ORDERBY 子句中指定列号。 3、EXCEPT 运算符 EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复 行而派生出一个结果表。 当 ALL 随EXCEPT 一起使用时 (EXCEPTALL), 不 消除重复 行。 在下列 EXCEPT 运算符的示例中, 查 询返回收入超过 $21,000 但没有经理职位且工 龄 为8 年或更长的所有人员的姓名。 SELECTID,NAMEFROMSTAFFWHERESALARY > 21000 EXCEPT SELECTID,NAMEFROMSTAFFWHERE JOB='Mgr' ANDYEARS < 8 各个查询的结果在关于 UNION 的一节中列出。上面的语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 45 4、INTERSECT 运算符 INTERSECT 运算符通过只包括 TABLE1 和TABLE2 中都有的行并消除所 有重复行 而派生出一个结果表。 当 ALL 随INTERSECT 一起使用时 (INTERSECTALL), 不 消除 重 复行。 在下列 INTERSECT 运算符的示例中, 查询返回收入超过 $21,000 有管理责任且工 龄 少于 8年的雇员的姓名和 ID。 SELECTID,NAMEFROMSTAFFWHERESALARY > 21000 INTERSECT SELECTID,NAMEFROMSTAFFWHERE JOB='Mgr' ANDYEARS < 8 各个查询的结果在关于 UNION 的一节中列出。 这两个使用 INTERSECT 的查询的 结 果为: 5、当使用 UNION、EXCEPT 以及 INTERSECT 运算符时,记住下列事项: 运算 符的 查 询 选 择 列 表 中的 所 有 对 应 项 必须 是 相 容 的 。 有 关更 多 信 息 , 参 见 SQL Reference 中的数据类型相容性表。 ORDERBY 子句(如果使用该子句的话)必须放在最后一个带有集合运算符的查询后 面。 对 于每个运算符来说, 如 果列的名称与查询的选择列表中对应项的名称相同, 则 该列 名 只能在 ORDERBY 子句中使用。 在具有相同数据类型和相同 长度的列之 间进行的运 算会产生一 个具有该类 型和长度的 列 。 针对 UNION、EXCEPT 以及 INTERSECT 集合运算符的结果, 参 见 SQL Reference 中 结果数据类型的规则。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 46 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 谓词 谓词 谓词 谓词 1、谓词 谓词允许您构造条件,以便只处理满足这些条件的那些行。基本谓词在 选择行 讨论。本节讨论 IN、BETWEEN、LIKE、EXISTS 以及定量谓词。 2、使用 IN 谓词 使用 IN 谓词将一个值与其他几个值进行比较。例如: SELECTNAME FROMSTAFF WHEREDEPTIN(20, 15) 此示例相当于: SELECTNAME FROMSTAFF WHEREDEPT = 20 ORDEPT = 15 当子查询返回一组值时,可使用 IN 和NOTIN 运算符。例如,下列查询列出负责项 目MA2100 和OP2012 的雇员的姓: SELECTLASTNAME FROMEMPLOYEE WHEREEMPNOIN (SELECTRESPEMP FROMPROJECT WHEREPROJNO = 'MA2100' ORPROJNO = 'OP2012') 计算一次子查询, 并 将结果列表直接代入外层查询。 例 如, 上 面的子查询选择雇员编 号 10 和330,对外层查询进行计算,就好象 WHERE 子句如下: WHEREEMPNOIN(10, 330) 子查询返回的值列表可包含零个、一个或多个值。 3、使用 BETWEEN 谓词 使用 BETWEEN 谓词将一个值与某个范围内的值进行比较。 范 围两边的值是包括在 内 的,并考虑 BETWEEN 谓词中用于比较的两个表达式。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 47 下一示例寻找收入在 $10,000 和$20,000 之间的雇员的姓名: SELECTLASTNAME FROMEMPLOYEE WHERESALARYBETWEEN 10000 AND 20000 这相当于: SELECTLASTNAME FROMEMPLOYEE WHERESALARY >= 10000 ANDSALARY <= 20000 下一个示例寻找收入少于 $10,000 或超过 $20,000 的雇员的姓名: SELECTLASTNAME FROMEMPLOYEE WHERESALARYNOTBETWEEN 10000 AND 20000 4、使用 LIKE 谓词 使用 LIKE 谓词搜索具有某些模式的字符串。通过百分号和下划线指定模式。 下划线字符 (_)表示任何单个字符。 百分号 (%)表示零或多个字符的字符串。 任何其他表示本身的字符。 下列示例选择以字母 'S'开头长度为 7 个字母的雇员名: SELECTNAME FROMSTAFF WHERENAMELIKE'S______' 下一个示例选择不以字母 'S'开头的雇员名: SELECTNAME FROMSTAFF WHERENAMENOTLIKE'S%' 5、使用 EXISTS 谓词 可使用子查询来测试满足某个条件的行的存在性。 在 此情况下, 谓 词 EXISTS 或NOT EXISTS 将子查询链接到外层查询。 当用 EXISTS 谓词将子查询链接到外层查询时,该子查询不返回值。相反,如果子查 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 48 询的回答集 包含 一个 或更 多个 行,则 EXISTS 谓词为真; 如果 回答 集不 包含 任何行 ,则 EXISTS 谓词为假。 通常将 EXISTS 谓词与相关子查询一起使用。 下 面示例列出当前在项目 (PROJECT) 表 中没有项的部门: SELECTDEPTNO,DEPTNAME FROMDEPARTMENTX WHERENOTEXISTS (SELECT* FROMPROJECT WHEREDEPTNO = X.DEPTNO) ORDERBYDEPTNO 可通过在外层查询的 WHERE 子句中使用 AND 和OR 将EXISTS 和NOTEXISTS 谓词与其他谓词连接起来。 6、定量谓词 定量谓词将一个值和值的集合进行比较。 如 果全查询返回多个值, 则 必须通过附加后 缀 ALL、ANY 或SOME 来修改谓词中的比较运算符。这些后缀确定如何在外层谓词中处理 返回的这组值。使用 >比较运算符作为示例(下面的注释也适用于其他运算符) : 表达式 > ALL(全查询) 如果该表达式大于由全查询返回的每个单值, 则 该谓词为真。 如 果全查询未返回值, 则 该谓词为真。如果指定的关系至少对一个值为假,则结果为假。注意: <>ALL 定量谓词相 当于 NOTIN 谓词。 下列示例 使用 子查 询和 > ALL 比较来寻 找收 入超 过所 有经 理的 所 有雇 员的 姓名 和职 业: SELECTLASTNAME,JOB FROMEMPLOYEE WHERESALARY > ALL (SELECTSALARY FROMEMPLOYEE WHERE JOB='MANAGER') 表达式 > ANY(全查询) 如果表达式至少大于由全查询返回的值之一, 则 该谓词为真。 如 果全查询未返回值, 则 该谓词为假。注意: =ANY 定量运算符相当于 IN 谓词。 表达式 > SOME(全查询) Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 49 SOME 与ANY 同义。 第六 部分 : 高级 SQLSQLSQL SQL SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 用约 束和 触发器 实施 商业 规则 用约 束和 触发器 实施 商业 规则 用约 束和 触发器 实施 商业 规则 用约 束和 触发器 实施 商业 规则 在商界, 我们的确通常需要确保始终实施某些规则。 例 如, 参与项目的雇员必须被 雇 用。 或者想要某些事件有计划地发生。例如, 如果销售员售出一批商品,则应增加其 佣 金。 DB2 通用数据库为此提供了一套有用的方法。 唯一约束是禁止在表的一列或多列中 出 现重复值的规则。 参考完整性约束确保在整个指定的表中数据一致性。 表检查约束是一 些 条件, 它 们定义为表定义的一部分, 限 制一列或多列中使用的值。 触 发器允许您定义一组 操 作, 这 些操作通过对指定的表进行删除、 插 入或更新操作来执行或触发。 触 发器可用于写 入 其他表、修改输入值以及发布警报信息。 第一节提供关键字的概念性概述。 接 着, 通 过示例和图表进一步探讨参考完整性、 约 束 以及触发器。 1、关键字 关键字是可用来标识或存取特定行的一组列。 由不止一列组成的关键字称为组合关键字。 在 具有组合关键字的表中, 组 合关键字中 各 列的排序不受这些列在表中排序的约束。 唯一关键字 唯一关键 字 被定 义为 它 的任 何值 都 不相 同。 唯 一关 键字 的 列不 能包 含 空值 。在 执行 INSERT 和UPDATE 语句期间, 数据库管理程序强制执行该约束。 一 个表可以有多个唯 一 关键字。 唯 一关键字是可选的, 并 且可在 CREATETABLE 或ALTERTABLE 语句中定义 。 主关键字 主关键字是一种唯一关键字, 表 定义的一部分。 一 个表不能有多个主关键字, 并 且主 关 键字的列不能包含空值。 主 关键字是可选的, 并 且可在 CREATETABLE 或ALTERTABLE 语句中定义。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 50 外部关键字 外部关键字在参考约束的定义中指定。 一 个表可以有零个或多个外部关键字。 如 果组 合 外部关键字的值的任何部分为空,则该值为空。外部关键字是可选的,并且可在 CREATE TABLE 语句或 ALTERTABLE 语句中定义。 2、唯一约束 唯一约束确保关键字的值在表中是唯一的。 唯 一约束是可选的, 并 且可以通过使用指 定 PRIMARYKEY 或UNIQUE 子句的 CREATETABLE 或ALTERTABLE 语句来 定义唯 一约束。 例 如, 可 在一个表的雇员编号列上定义一个唯一约束, 以 确保每个雇员有唯一的 编 号。 3、参考完整性约束 通过定义唯一约束和外部关键字, 可 以定义表与表之间的关系, 从 而实施某些商业规 则。 唯一关键和外部关键字约束的组合通常称为参考完整性约束。 外 部关键字所引用的唯一约 束 称为父关键字。 外 部关键字表示特定的父关键字, 或与特定的父关键字相关。 例 如, 某规 则 可能规定每个雇员 ( EMPLOYEE 表) 必须属于某现存的部门 ( DEPARTMENT 表)。因此, 将EMPLOYEE 表中的 “部门号 ”定义为外部关键字, 而将 DEPARTMENT 表中的 “部门号 ” 定义为主关键字。下列图表提供参考完整性约束的直观说明。 图4. 外部约束和主约束定义关系并保护数据 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 51 4、表检查约束 表检查约束指定对于表的每行都要进行判定的条件。 可 对个别列指定检查约束。 可 使 用 CREATE 或ALTERTABLE 语句添加检查约束。 下列语句创建具有下列约束的表: 部门编号的值必须在范围 10 至100 内 雇员的职务只能为下列之一: "Sales"、"Mgr"或"Clerk" 1986 年之前雇用的每个雇员的工资必须超过 $40,500。 CREATETABLEEMP (IDSMALLINTNOTNULL, NAME VARCHAR(9), DEPTSMALLINTCHECK(DEPTBETWEEN 10 AND 100), JOB CHAR(5) CHECK(JOBIN('Sales', 'Mgr', 'Clerk')), HIREDATEDATE, SALARY DECIMAL(7,2), COMM DECIMAL(7,2), PRIMARYKEY(ID), CONSTRAINTYEARSALCHECK(YEAR(HIREDATE) >= 1986 ORSALARY Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 52 > 40500) ) 仅当条件判定为假时才会违反约束。例如,如果插入行的 DEPT 为空值,则插入继续 进行而不出错,尽管 DEPT 的值应该象约束中定义的那样在 10 和100 之间。 下列语句将一个约束添加至名为 COMP 的EMPLOYEE 表中,该约束为雇员的总报 酬必须超过 $15,000: ALTERTABLEEMP ADDCONSTRAINTCOMPCHECK(SALARY + COMM > 15000) 将检 查表中现存的行以确保这些行不违反新约束。可通过使用如下的SET CONSTRAINTS 语句将此检查延期: SETCONSTRAINTSFOREMPOFF ALTERTABLEEMPADDCONSTRAINTCOMPCHECK(SALARY + COMM > 15000) SETCONSTRAINTSFOREMPIMMEDIATECHECKED 首先使用 SETCONSTRAINTS 语句以延期对表的约束检查。 然 后可将一个或多个约 束 添加至表而不检查这些约束。 接 着再次发出 SETCONSTRAINTS 语句, 反 过来将约束检 查 打开并执行任何延期的约束检查。 5、触发器 一个触发器定义一组操作,这组操作通过修改指定基表中数据的操作来激活。 可使用触发器来执行对输入数据的验证; 自 动生成新插入行的值; 为 了交叉引用而读 取 其他表; 为 了审查跟踪而写入其他表; 或 通过电子邮件信息支持警报。 使 用触发器将导致 应 用程序开发及商业规则的全面实施更快速并且应用程序和数据的维护更容易。 DB2 通用 数 据 库 支 持几 种 类 型 的 触 发 器 。 可 定 义 触 发 器在 DELETE、INSERT 或 UPDATE 操作之前或之后激活。每个触发器包括一 组称为触发操作的 SQL 语句,这组语 句可包括一个可选的搜索条件。 可进一步定义后触发器以对每一行都执行触发操作, 或 对语句执行一次触发操作, 而 前 触发器总是对每一行都执行触发操作。 在INSERT、UPDATE 或DELETE 语句之前使用触发器, 以 便在执行触发操作之前 检 查某些条件, 或 在将输入值存储在表中之前更改输入值。 使 用后触发器, 以 便在必要时传 播 值或执行其他任务,如发送信息等,这些任务可能是触发器操作所要求的。 下列示例说明了前触发器和后触发器的使用。 考 虑一个记录并跟踪股票价格波动的应 用 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 53 程序。该数据库包含两个表, CURRENTQUOTE 和QUOTEHISTORY,定义如下: CREATETABLECURRENTQUOTE (SYMBOL VARCHAR(10), QUOTE DECIMAL(5,2), STATUSVARCHAR(9)) CREATETABLEQUOTEHISTORY (SYMBOL VARCHAR(10), QUOTE DECIMAL(5,2), TIMESTAMPTIMESTAMP) 当使用如下语句更新 CURRENTQUOTE 的QUOTE 列时: UPDATECURRENTQUOTE SETQUOTE = 68.5 WHERESYMBOL = 'IBM' 应更新 CURRENTQUOTE 的STATUS 列以反映股票是否: 在升值 处于本年度的新高 在下跌 处于本年度的新低 价位稳定 这通过使用下列前触发器来实现: (1) CREATETRIGGERSTOCK_STATUS NOCASCADEBEFOREUPDATEOFQUOTEONCURRENTQUOTE REFERENCINGNEWASNEWQUOTEOLDASOLDQUOTE FOREACHROWMODE DB2SQL (2) SETNEWQUOTE.STATUS = (3) CASE Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 54 (4) WHENNEWQUOTE.QUOTE >= (SELECTMAX(QUOTE) FROMQUOTEHISTORY WHERESYMBOL = NEWQUOTE.SYMBOL ANDYEAR(TIMESTAMP) = YEAR(CURRENTDATE)) THEN'High' (5) WHENNEWQUOTE.QUOTE <= (SELECTMIN(QUOTE) FROMQUOTEHISTORY WHERESYMBOL = NEWQUOTE.SYMBOL ANDYEAR(TIMESTAMP) = YEAR(CURRENTDATE)) THEN'Low' (6) WHENNEWQUOTE.QUOTE > OLDQUOTE.QUOTE THEN'Rising' WHENNEWQUOTE.QUOTE < OLDQUOTE.QUOTE THEN'Dropping' WHENNEWQUOTE.QUOTE = OLDQUOTE.QUOTE THEN'Steady' END (1) 此代码块将名为STOCK_STATUS 的触发器定义为一个应该在更新 CURRENTQUOTE 表的QUOTE 列之前激活的触发器。第二行指定,在将 CURRENTQUOTE 表的实际更新所引起的任何 更改应用于 数据库之前 ,要应用触 发操作。 第二行也意味着触发操作将不会激活任何其他触发器。 第 三行指定一些名称, 必 须将这些 名 称作 为列名的限定符用于新值(NEWQUOTE) 和旧 值 (OLDQUOTE)。用 这 些 相 关 名 (NEWQUOTE 和OLDQUOTE)限定的列名称为转换变量 。第四行表 示应对每一 行都执 行触发操作。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 55 SQL SQL SQL SQL 入门入门入门 入门 ::: : 连接连接连接 连接 从两个或更多个表中组合数据的过程称为连接表。 数 据库管理程序从指定的表中形 成 行的所有组合。 对于每个组合, 它都测试连接条件。连接条件是带有一些约束的搜索 条 件。有关约束的列表,参考 SQL Reference。 注意: 连 接条件涉及的列的数据类型不必相同; 然而, 这 些数据类型必须相容。 计算 连 接条件的方式与计算其他搜索条件的方式相同,并且使用相同的比较规则。 如果未指定连接条件, 则 返回在 FROM 子句中列出的表中行的所有组合, 即 使这些 行 可能完全不相关。该结果称为这两个表的交叉积。 本节中的示例基于下面两个表。 这 两个表只是样本数据库中表的简化形式, 在 样本数 据 库中并不存在。这两个表一般用来概述关 于连接的重点。 SAMP_STAFF 列出未作为合同 工雇用的雇员的姓名以及这些雇员的职务说明,而 SAMP_PROJECT 则列出雇员(合同工 和全职人员)的姓名以及这些雇员所参与的项目。 这些表如下: 图5. SAMP_PROJECT 表 图6. SAMP_STAFF 表 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 56 下列示例产生两个表的交叉积。因未指定连接条件,所以给出了行的所有组合: SELECTSAMP_PROJECT.NAME, SAMP_PROJECT.PROJ,SAMP_STAFF.NAME,SAMP_STAFF.JOB FROMSAMP_PROJECT,SAMP_STAFF 此语句产生下列结果: 两个主要的连接类型是内连接和外连接。到目前为止,所有示例中使用的都是内连接。 内连接只保留交叉积中满足连接条件的那些行。 如 果某行在一个表中存在, 但 在另一个表 中 不存在,则结果表中不包括该信息。 下列示例产生两个表的内连接。该内连接列出分配给某个项目的全职雇员信息: SELECTSAMP_PROJECT.NAME, SAMP_PROJECT.PROJ,SAMP_STAFF.NAME,SAMP_STAFF.JOB FROMSAMP_PROJECT,SAMP_STAFF WHERESAMP_STAFF.NAME = SAMP_PROJECT.NAME Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 57 或者,也可以指定如下内连接: SELECTSAMP_PROJECT.NAME, SAMP_PROJECT.PROJ,SAMP_STAFF.NAME,SAMP_STAFF.JOB FROMSAMP_PROJECTINNERJOINSAMP_STAFF ONSAMP_STAFF.NAME = SAMP_PROJECT.NAME 结果是: 注意 :该内连接的结果由右表和左表中姓名列的值匹配的行组成-'Haas' 和 'Thompson' 都包括在列出所有全职雇员的 SAMP_STAFF 表中以及列出分配给某个项目的 专职和合同雇员的 SAMP_PROJECT 表中。 外连接是内连接和左表和/或右表中未包括内连接中的那些行的并置。 当 对两个表执 行 外连接时,可任意将一个表指定为左表而将另一个表指定为右表。外连接有三种类型: 左外连接包括内连接和左表中未包括在内连接中的那些行。 右外连接包括内连接和右表中未包括在内连接中的那些行。 全外连接包括内连接以及左表和右表中未包括在内连接中的行。 使用 SELECT 语句来指 定要 显示 的列 。在 FROM 子句中, 列出 后跟 关键 字 LEFT OUTERJOIN、RIGHTOUTERJOIN 或FULLOUTERJOIN 的第一个表的名称。 接着需 要 指定后跟 ON 关键字的第二个表。 在 ON 关键字后面, 指 定表示要连接的表之间关系的 连 接条件。 在下列示例中, 将 SAMP_STAFF 指定为右表, 而 SAMP_PROJECT 则被指定为左 表。 通过使用 LEFTOUTERJOIN,列出所有全 职和 合同雇 员( 在 SAMP_PROJECT 中列出) 的姓名和项目编号, 如 果是全职雇员 ( 在 SAMP_STAFF 中列出),还列 出这些雇员的职位: SELECTSAMP_PROJECT.NAME,SAMP_PROJECT.PROJ, SAMP_STAFF.NAME,SAMP_STAFF.JOB FROMSAMP_PROJECTLEFTOUTERJOINSAMP_STAFF ONSAMP_STAFF.NAME = SAMP_PROJECT.NAME 此语句产生下列结果: Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 58 所有列中都具有值的那些行是该内连接的结果。 这 些都是满足连接条件的行: 'Haas' 和 'Thompson' 既在 SAMP_PROJECT(左表) 中列出又在 SAMP_STAFF(右表) 中列出。 对 于不满足连接条件的行, 右 表的列上出现空值: 'Lutz' 和'Walker' 都是在 SAMP_PROJECT 表中列出的合同雇员,因而未在 SAMP_STAFF 表中列出。注意:左表中的所有行都包括 在结果集中。 在下一个 示例 中, 将 SAMP_STAFF 指定为右 表而 SAMP_PROJECT 则被指定 为左 表。通过使用 RIGHTOUTERJOIN 列出所有专职雇员(在 SAMP_STAFF 中列出)的姓 名和工作职位, 如 果将这些雇员分配给了某个项目 ( 在 SAMP_PROJECT 中 列 出 ) , 还列 出 他们的项目编号: SELECTSAMP_PROJECT.NAME, SAMP_PROJECT.PROJ,SAMP_STAFF.NAME,SAMP_STAFF.JOB FROMSAMP_PROJECTRIGHTOUTERJOINSAMP_STAFF ONSAMP_STAFF.NAME = SAMP_PROJECT.NAME 结果为: 象在左外连接中一样, 所 有列中都具有值的那些行是内连接的结果。 这 些都是满足连 接 条件的行: 'Haas'和'Thompson'既在 SAMP_PROJECT(左表)中列出又在 SAMP_STAFF (右表)中列出。对于不满足连接条件的行, 右表的列上出现空值: 'Lucchessi'和'Nicholls' 都是未分配项目的专职雇员。 虽 然他们在 SAMP_STAFF 中列出, 但 未在 SAMP_PROJECT 中列出。注意:右表中的所有行都包括在结果集中。 下一个示例对 SAMP_PROJECT 表和 SAMP_STAFF 表使用 FULLOUTERJOIN。该 示例列出所有专职雇员(包括未分配项目的雇员)和合同雇员的姓名: SELECTSAMP_PROJECT.NAME,SAMP_PROJECT.PROJ, SAMP_STAFF.NAME,SAMP_STAFF.JOB FROMSAMP_PROJECTFULLOUTERJOINSAMP_STAFF Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 59 ONSAMP_STAFF.NAME = SAMP_PROJECT.NAME 结果为: 此结果包括左外连接、 右 外连接以及内连接。 列 出所有专职雇员和合同雇员。 正 如左 外 连接和右外连接一样,对于不满足连接条 件的值,相应列中 出现空值。 SAMP_STAFF 和 SAMP_PROJECT 中的每一行都包括在结果集中。 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 复杂 查询 复杂 查询 复杂 查询 复杂 查询 1、复杂查询 DB2 通用数据库允许您通过使用 ROLLUP 和CUBE 分组、 合 并及查看单个结果集 中 的多列。这种新型而强大的功能增强并简化了基于数据分析的 SQL。 有很多方法可从数据库中抽取有用信息。可执行递归查询从现存数据集中产生结果表。 2、ROLLUP 和CUBE 查询 在查询的 GROUPBY 子句中指定 ROLLUP 和CUBE 运算。 ROLLUP 分组产生包 含常规分组行和小计行的结果集。 CUBE 分组产生包含来自 ROLLUP 和交叉制表行中的 行 的结果集。所以对于 ROLLUP,可获取每人每月的销售量 以及每月销 售总量和总 部总量。 对于 CUBE,将包括每人销售总量的附加行。参见 SQL Reference 以了解更详细的情况。 3、递归查询 递归查询是迭代使用结果数据来确定进一步结果的查询。 可 以把这想象成在一棵树上 或 一幅图中来回移动。 使 用递归查询的常见示例包括材料单应用程序、 订 票系统、 网 络计划 和 调度。 递归查询是使用包括引用自己名称的的公共表表达式来编写的。参见 SQL Reference 以获取递归查询的示例。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 60 第七 部分 :定 制和 增强 数据操 作 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 用户 定义 类型 用户 定义 类型 用户 定义 类型 用户 定义 类型 单值类型是与现存类型 (它的 “源”类型) 共享其内部表示的用户定义数据类型, 但 对 于大多数运算来说,认为单值类型是独立和不兼容的。例如,您可能想定义年龄类型、 重量类型以及高度类 型,所有 这些类 型都有相 当不同的 语义,但 都使用 内部数据 类型 INTEGER 作为它们的内部表示。 下列示例说明了命名为 PAY 的单值类型的创建: CREATEDISTINCTTYPEPAYAS DECIMAL(9,2) WITHCOMPARISONS 虽然 PAY 有与 内 部 数 据 类 型 DECIMAL(9,2)相同 的表示,但还是认为它是与 DECIMAL(9,2)或任何其他类型不可比的独 立类型。它 只能与相同 的单值类型 比较。并且, 会影响到按 DECIMAL 使用的运算符和函数将在此不适用。例如,具有 PAY 数据类型的 值不能与具有 INTEGER 数据类型的值相乘。 因 此, 您 必须编写只应用于 PAY 数据类型 的 函数。 使用单值数据类型可限制偶然错误。例如 ,如果将 EMPLOYEE 表的 SALARY 列定 义为 PAY 数据类型,则不能将该列添加至 COMM,即使它们的源类型相同。 单值数据类型支持类型转换。 源 类型可以转换为单值数据类型, 单 值数据类型也可以 转 换为源类型。 例 如, 如 果将表 EMPLOYEE 的SALARY 列定义为 PAY 数据类型, 则 下 列 示例将不会在比较运算符处出错。 SELECT*FROMEMPLOYEE WHEREDECIMAL(SALARY) = 41250 DECIMAL(SALARY)返回一个十进制数据类型。 相 反地, 数 字数据类型可以转换为 PAY 类型。例如,可以使用 PAY(41250) 来转换数字 41250 的类型。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 61 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 大对 象 大对 象 大对 象 大对 象 (LOB)(LOB)(LOB) (LOB) 1、大对象 (LOB) 术语大对象及其缩写 词 LOB 用于表示三种数据类 型: BLOB、CLOB 或DBCLOB。 这些类型可以包含诸如音频、图片以及文档等对象的大量数据。 二进制大对象 (BLOB) 是变长字符串, 以 字节进行量度, 最 大长度可达 2 吉字节。BLOB 主要用来保存非传统数据,如图片、声音以及混合媒体等。 字符大对象 (CLOB) 是变长字符串, 以 字节进行量度, 最 大长度可达 2 吉字节。 CLOB 用于存储大的单字节字符集数据,如文档等。 CLOB 被认为是字符串。 双字节字符大对 象 (DBCLOB) 是最大长度可达 2 吉字节的双字节 字符变 长字符 串( 1 073 741 823 双字节字符)。DBCLOB 用于存储大的双字节字符集数据, 如 文档等。 DBCLOB 被认为是图形字符串。 2、操作大对象 (LOB) 由于 LOB 值可以很大, 所 以将它们从数据库服务器传送至客户机应用程序可能要花 费 一些时间。 然 而, 一般一次处理 LOB 值的一部分, 而 不是将它们作为一个整体处理。 对 于 应用程序不需要 ( 或不想要) 将 整个 LOB 值存储在应用程序内存中的那些情况, 应 用程 序 可以通过大对象定位器变量引用此值。 然后后续语句可以使用定位器对数据执行操作, 而 不必检索整个大对象。 定 位器变量 用 来减少应用程序的存储器需求,并通过减少客户机与服务器之间的数据流而改进性能。 另一个机制是文件引用变量。 它 们用来直接对文件检索大对象或直接从文件来更新表 中 的大对象。 文 件引用变量用来减少应用程序的存储器需求, 因 为这些变量不必存储大对象 数 据。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 62 SQL SQL SQL SQL 入门 入门 入门 入门 ::: : 目录 视图 的介绍 目录 视图 的介绍 目录 视图 的介绍 目录 视图 的介绍 1、目录视图的介绍 DB2 为每个数据库创建并维护一个系统目录表扩充集。 这 些表包含关于数据库对象 ( 如 表、 视图、 程序包、 参考完整性关系、 函数、 单值类型以及触发器等) 的逻辑结构和物理 结 构的信息。 这 些表是在创建数据库时创建的, 并 在正常操作过程中得到更新。 不 能显式创 建 或卸下它们,但可以查询和查看其内容。 2、从系统目录中选择行 目录视图象任何其他数据库视图一样。 可以使用 SQL 语句来查看数据, 确切地说, 就 是使用查看系统中任何其他视图的相同方式。 可以在 SYSCAT.TABLES 目录中找到关于表的非常有用的信息。要寻找已创建的现 存 表的名称,发出一个类似以下的语句: SELECTTABNAME,TYPE,CREATE_TIME FROMSYSCAT.TABLES WHEREDEFINER = USER 此语句产生下列结果: 下列列表包括与本书讨论的与主题有关的目录视图。 还 有很多其他目录视图, 它 们详 细 地在 SQL Reference 和管理指南中列出。 Christen 整理: SQL 入门教程 但求忙而不乱 / 一睡解千愁 Thanks for all the support from Samuel、Guitang、Robin、Alan、Maoxiang、Panrui and Pinkey , etc. 63 --全文完! Christen 整理于 2007 年6月6日。
还剩62页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 15 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

quchangfu

贡献于2010-12-01

下载需要 15 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf