作者:empty 出版社:empty |
上机目的
1、了解并熟悉DB2环境
2、了解并熟悉DB2的产品
3、熟悉使用命令行处理器
二、预备知识
1、DB2的基本知识
DB2 是IBM公司的关系型数据库产品,是目前最流行的大型数据库之一,用户可以用结构化查询语言(SQL)对数据库对象进行创建、更新以及控制。它可以运行在不同的操作系统平台上,如大型操作系统 OS/390TM、MVS/ESA TM 、VM及VSE;中型操作系统 OS/400®、AIX、HP-UX、Solaris、SCO UNIX及SINIX;单用户及局域网操作系统 OS/2、Windows NT、Windows 95,同时它还支持DOS、Windows、Macintosh平台上的应用。
DB2能存储所有类型的电子信息,它包括传统的关系型数据、结构化以及半结构化的二进制信息、多种语言文档及文本、图片、多媒体以及与特殊应用有关的信息。因此被称为通用数据库(Universal Database)。(源码网整理:www.codepub.com)
DB2通用数据库是由DB2 Parallel Edition V1.2 和 DB2 Common Server V2.1.2两个产品组成的,这两个产品是在DB2/6000 Version 1的基础上发展起来的,但其侧重点不同,前者用于查询运行在多并行处理器上的大型数据库,为IBM 的RS/6000TM SPTM 优化查询能力而开发;后者是为满足UNIX、OS/2 、Windows NT平台上的通用SQL服务器市场而设计,称为数据库服务器。DB2 Parallel Edition V1.2和DB2 Common Server V2.1.2的结合使DB2拥有丰富的功能不仅具有从膝上型电脑到巨型并行系统、支持大量并行事务的处理能力,而且能支持联机分析或OLAP处理。OLAP处理是以在数据仓库、数据挖掘或决策支持等应用中由少数用户运行非常复杂的查询为显著特征。DB2 UDB也包括Web集成,并将Net.Data TM 包含在数据库服务器之中,还有一些集成工具如数据复制和作业调度器。
2、DB2的主要软件部件
DB2 UDB Version5有四种不同的数据库服务器产品:单用户版、工作组版、企业版及企业扩展版,功能也依次越来越强。其软件部件非常丰富(如图1-1所示),主要软件部件有:
数据库引擎(Database Engine) 提供DB2基本的主要功能。它管理和控制所有对数据的访问、提供事务管理和数据保护、确保数据一致性和并发控制。
命令行处理器(Command Line Processor , CLP) 用于动态执行SQL请求或DB2的命令。运用CLP可以通过DB2® Connect Personal Edition 或 DB2 Connect Enterprise Edition访问本地工作站的数据库、远程工作站的数据库或远程分布式关系数据库体系结构应用服务器的数据库(remote Distributed Relational Database Architecture Application Server , DRDA AS database)。
管理工具(Administration Tools) 用于帮助管理数据库的图形用户界面的工具的集合。包括:
—— 控制中心(Control Center),进行配置、备份与恢复、目录管理。
—— 命令中心(Command Center),执行命令和生成命令脚本。
—— 脚本中心(Script Center),执行SQL和生成SQL脚本。
—— 事件分析器(Event Analyzer),分析事件信息。
—— 运行日志(Journal),分析提交作业的状态。
—— 工具设置(Tools Settings),创建复制、设置终止符和创建Alter Center选件。
应用(Application) 可以用下列方式访问数据库:
—— Embedded SQL
—— Call Lever Interface ODBC
—— Java
—— Application Programming Interfaces(APIs)
外部工具(External tools)提供相应的附加功能。
图1-1 DB2的主要软件部件
在DB2的四个版本中,除了单用户版外工作组版、企业版及企业扩展版都采用C/S模式,用户在客户端安装了DB2 Client Application Enabler 后为访问远端服务器上的数据提供了环境,在客户端的Command Line Processor (CLP)下可以通过执行SQL语句来访问服务器上的数据。(源码网整理:www.codepub.com)
3、DB2的主要产品部件
DB2的一系列相关产品适用于通用的数据库平台,提供了一个功能齐全、健壮性强的关系数据库管理系统(RDBMS)。其主要产品部件如图1-2所示有:
DB2 Communication Support提供了远程客户支持,扩展了DB2的功能。DRDA(分布关系数据库体系结构,Distributed Relational Database Architecture)应用请求者代表来自诸如MVS TM 、VM和OS/400的请求。
Client Application Enabler(CAE)产品包含了由DB2产品提供使得应用能在远程节点上运行和访问DB2数据库服务器的部分功能。
DB2 Personal Developer’s Edition不仅包含了由CAE提供的功能,而且为客户工作站提供了一个完备的开发环境。这些工具箱包括编程文档、代码样例、预编译器、头文件或其他应用开发工具。PDE不包括DB2数据库服务器的功能。其支持的语言有C、C++、COBOL、REXX和FORTRAN。
DB2 Connect提供了DRDA应用请求者的功能。具有通讯支持(Communications Support),DB2 Connect使得运行在UDB平台上的应用能访问和更新数据库中的数据。
图1-2 DB2的产品部件
4、命令行处理器(CLP)的使用
用户可用很多方法与DB2 UDB系统交互,其中最简单直接的方法称为命令行处理器CLP(Command Line Processor),对单用户和服务器版本均提供。CLP接受和处理来自键盘或文件的命令和SQL语句,并显示它们的结果。CLP还可执行以DB2为提示符的操作系统命令,其功能可分为下列几类:
1)、与CLP自己行为有关的一类命令。如说明输入来源和输出去处,以及如何处理错误等这类属于控制选项的命令。
2)、对数据库存取和操作的SQL语句类。用CLP执行SQL语句作为交互式SQL语句。
3)、调用系统实用工具的命令类。如创建新数据库,并对它们的配置加以说明,以及删除数据库的命令;用宿主语言写出新数据库应用,为编译和连接作准备用的命令;数据出错后使之恢复和复制时使用的命令等等。
下面是在CLP下进行数据库的连接和断开。
数据库的连接
只有当系统管理员为用户建立了一个用户名,并赋予登录密码和一定的权限后,用户才能访问数据库,即对数据库里的数据进行存取。首先进入CLP,如果要连接到名为Sample的数据库,在CLP下输入如下命令:
CONNET TO SAMPLE USER userid USING password
其中USERID为用户名,PASSWORD为该用户的密码。
如果连接成功,会出现如下信息:
Database Connection Information
Database product = DB2/2 5.0.0
SQL authorization ID = USERID
Local database alias = SAMPLE
如果连接失败,假设是 USERID 或 PASSWORD 输入错误,系统将返回如下信息:
SQL1403N The username and / or password supplied is Incorrect.
SQLSTATE=08004
每个SQL语句执行结果用2个代码表示执行的成功或失败的错误类型分别是SQLCODE和SQLSTATE。在DB2系列产品中,SQLCODE用整数表示,当它为零时表示执行成功,为负整数时表示执行有错,为正整数(非零)时表示警告或“无行可修改”之类的问题。而SQLSTATE是由ANSI/ISO SQL标准定义的5个新字符表示,它与SQLCODE表示相同的信息但是不同的编码方法。当CLP在交互方式下,无论何时一个SQL语句执行失败,CLP都会都将返回一个错误信息,由信息标识、简要说明和SQLSTATE三部分代码组成。如想得到更详细的SQLCODE或SQLSTATE的信息,可用“?”后跟SQLCODE或SQLSTATE编号,如:
? 08004
? SQL1403N
数据库的断开
当对数据处理、或在数据库上的应用执行完毕后,应该断开与数据库的连接,所执行的命令为:
1)、DISCONNECT SAMPLE
2)、DISCONNECT CURRENT
3)、DISCONNECT ALL
其中1)表示对开与SAMPLE数据库的连接;2)表示断开与当前数据库的连接;3)表示断开与所有数据库的连接。
三、上机实验
1、按数据库管理员分配的用户进入DB2,熟悉DB2的环境和产品。
2、熟悉CLP下一些基本命令命令。
第二章 基表、视图以及授权控制
一、上机目的
1、掌握基表、视图及库模式定义
2、掌握并熟练运用基表的数据类型
3、掌握并熟练创建、删除、修改基表
4、掌握并熟练创建、删除视图
5、掌握授权控制
二、预备知识
在上一章中,我们对DB2有了一个整体的了解,本章将简要介绍一些关系数据库的知识。
1、基本概念
表 在一个关系型数据库中,所有数据都是以表的形式存放。表是由行和列组成。每个表有一个表名,表内的每一列有一个列名,每个列有列名、类型、长度等。表中的行之间无次序要求(但是,行可以按用户指定值的次序去检索)。
视图 视图是查看一个或多个表中数据的另一种形式。可将视图看作一个移动的窗口,通过它可以看到感兴趣的数据。这就是说,可“透过”视图来查看或修改数据。
视图并非一个物理表,它是从一个或多个基表或视图中导出的虚拟表。它与基表有相似和不同之处:
相同之处:它类似与基表,也是由若干列所组成,它包含若干数据行,对视图也可进行查询和其它操作,而且方法完全类似。
不同之处:一个视图并不分配空间,也不物理地包含数据,其数据存储在相应的基表中,通过查询获得它。虽可对视图进行插入、修改或删除操作,但具有一定的限制。
库模式 按ANSI/ISO SQL标准,对限定名用更通俗的观点,引用库模式名来表示,而不用建对象者的名字来表示。用库模式表示就如同把表按种类分类一样。
SQL的基本数据类型
类 型说 明
Char(x)定长(x)字符串,n≤254,缺省为1
Varchar(x)可变长字符串, n≤4,000,如n>254不能用GROUP BY,ORDER BY ,DISTINCT 和UNION ALL外的任何设置操作
Long Varchar可变长字符串
CLOB可变长字符串
Graphic(x)定长(x)双字节字符串,1≤x≤127
Vargraphic(x)大长度(x)双字节字符串,1≤x≤2,000,如n>127不能用GROUP BY,ORDER BY ,DISTINCT 和UNION ALL外的任何设置操作
Smallint两字节整数
Integer四字节整数
Real两字节单精度符点数
Double四字节双精度符点数
Decimal(p,s)带精度p和刻度s的十进制数,其中p是数字总位数,s是小数点后的位数
Date由年、月、日组成,如1991-10-27
Time由时、分、秒组成,如13:30:05
Timestamp由年、月、日、时、分、秒和微妙组成,如1991-10-27-13.30.05.000000
2、基表的创建、删除和修改
1)、上面讲述了一些基本的数据类型后,可以开始创建一个基表了。例如:
CREATE TABLE PERS
(ID SMALLINT NOT NULL,
NAME VARCHAR(9),
DEPT SMALLINT WITH DEFAULT 10,
JOB CHAR(5),
YEARS SMALLINT,
SALARY DECIMAL(7,2),
COM DECIMAL(7,2)
BIRTH_DATE DATE)
其中,PERS为基表名,ID为列名,SMALLINT为ID的数据类型,NOT NULL为 ID 的约束项,表示不为空。
2)、基表的删除,命令为DROP TABLE,如删除PERS基表相应的命令为:
DROP TABLE PERS;
3)、基表的修改
基表的修改可以修改其列名、数据类型、约束项。如在PERS中增加DESRIPTION VARCHAR(10)和 VALUE DECIMAL(8,2),其命令为
ALTER TABLE PERS
ADD COLUMN DESCRIPTION VARCHAR (10)
ADD COLUMN VALUE DECIMAL(8,2);
如在PERS中增加一个约束项使VALUE 50000,其命令为
ALTER TABLE PERS
ADD CONSTRAINT check1 CHECK (VALUE 50000);
如在PERS中删除该约束,其命令为
ALTER TABLE PERS
DROP CONSTRAINT check1 ;
基表中的约束有很多种,在以后的章节中将会详细地讨论。
注意,如果ALTER TABLE 语句中有多个ADD 和DROP子句,注意子句之间没有逗号。
3、视图的创建和删除
视图的创建用CREATE VIEW命令。下面的语句创建一个在STAFF表中部门为20职务不是经理的记录,但基表中的SALARY和COMMISSION列没有包含进去。
CREATE VIEW STAFF_ONLY
AS SELECT ID,NAME,DEPT,JOB,YEARS
FROM STAFF
WHERE JOB >’Mgr’ AND DEPT=20
你可以用下列语句显示创建的视图的内容:
SELECT *
FROM STAFF_ONLY
下面的语句是实现从STAFF和ORG表中选出每一部门及该部门的经理:
CREATE VIEW DEPARTMENT_MGRS
AS SELECT NAME,DEPTNAME
FROM STAFF,ORG
WHERE MANAGER=ID
视图的删除使用命令 DROP VIEW 。
4、特权和权限控制
对数据有特权存取和修改,是数据库管理系统的基本工作之一。特权可以管理多个数据库,在某个专用数据库上还有其它特权。一般特权都由用户组控制,不由单个用户管理。组的概念,在DB2的操作系统定义和管理。例如在AIX上,由系统管理界面工具(SMIT)设置,而在OS/2上,由用户概貌管理工具(UPM设置)。权限指某个数据库中特殊对象上完成各种活动的确认。如对表,视图上进行各种操作,权限是由单个用户或用户组控制。
1)、实例层的特权
DB2实例层有3种特权用来对实例数据库的管理。这些特权都由用户组控制,这些用户组的名字都被记录在数据库管理员配置文件中,组对实例层特权控制可看作执行如下一条命令:
GET DATABASE MANAGER CONFIGURATION;
系统管理特权(System Administration Authority)通常,特权或权限授予某个用户。再由该用户授予另一个用户,形成树结构的授予关系。树的根是系统管理部门或SYSADM,它是DB2的最高特权组织。它由一个组控制,该组中授予的成员都能去授予或调用其它特权和权限的能力。
系统控制特权(System Control Authority)。简称SYSCTRL是一个实例层特权,对系统资源确认。如SYSCTRL特权有权建立或删除数据库和表空间(存数据的物理存储单元)。SYSCTRL控制组名字存在数据库管理员配置名为SYSCTRL_GROUP参数中。安装DB2时,没给SYSCTRL特权,它由系统管理组成员授予SYSCTRL特权,用如下命令授权:
UPDATE DATABASE MANAGER CONFIGURATION
USING SYSCTRL_GROUP goodguys;
对SYSCTRL 要求有最小特权的系统命令如下:
CREATE 、ALTER、DROP TABLESPACE
CATALOG 、UNCATALOG
FORCE APPLICATION
RESTORE
系统维护特权(System Maintenance Authority)。简称SYSMAINT。一个SYSMAINT组记录在数据库管理员配置的SYSMAINT_GROUP参数中,安装系统时设置为null,系统管理组任何成员可对它授权。使用如下命令:
UPDATE DATABASE MANAGER CONFIGURATION
USING SYSMAINT_GROUP hackers;
对SYSMAINT最小特权要求的系统命令为:
UPDATE DATABASE CONFIGURATION
BACKUP、RESTORE
DB2START、DB2STOP
GET、RESET、 UPDATE MONITOR SWITCHES
2)、数据库层特权
数据库层特权是针对指定数据库而言,不是对DB2产品的一个实例。它们都记录在编目表的DBAUTH下。
数据库管理特权
DBADM是对指定数据库上所有对象的存取,修改权的确认。包括对表、索引、视图、软件包、以及存入数据库的每个项。它也包括在指定对象上数据授予权限的确认。DBADM的控制者也可对数据库层其它特权者授予用户权。
BINDADD特权
它是在数据库中由预编译和连接应用程序时建立软件包特权的确认。
CONNECT 特权
用SQL CONNECT 语句时,确认数据库连接正确的特权。
CREATETAB 特权
在数据库中建立时,建表者在一个表上接受CONTROL权限。
CREAT_NOT_FENCED特权
在数据库地址空间操作,用户定义函数特权确认。
授予特权的语句为:
BINDADD
CONNECT
GRANTCREATETABON DATABASE
CREATE_NOT_FENCED
IMPLICIT_SCHEMA
DBADM
TOUSER
GROUP
PUBLIC
AUTHORIZATION_NAME
可组合为如下命令:GRANT (BINDADD,CONNECT,…) ON DATABASE TO (USER,GROUP,PUBLIC,AUTHORIZATION_NAME),其中,第一个括号内的选项可选一个或多个,它们之间用逗号分隔,后面一个括号内的选项是从其中选一。后面的命令相同。
3)、表和视图的权限
表和视图的权限由GRANT 和REVOKE语句授予和撤消。如有SYSADM和DBADM特权的用户,可对一个表或视图授予任何权限。在表和视图上的权限有:
CONTROL、ALTER、DELETE、INDEX、INSERT、REFERENCES、SELECT和UPDATE权限。
授予特权的语句为:
ALTER
CONTROL
DELETE
INDEX
GRANTINSERTON table_name
REFERENCES (column_name) View_name
SELECT
UPDATE
TOUSER
GROUP
PUBLIC
AUTHORIZATION_NAME
注意:ALTER,INDEX,和REFERENCES特权不适用于视图。
4、索引权限
只有CONTROL权限可应用到索引上。它授予删去索引的权利力。CONTROL权限是在用户建索引时自动给用户的。它可由单个用户或用户组掌握。为了在一个索引上授予CONTROL权限,用户必须有SYSADM或DBADM特权。在各种索引上的CONTROL权限是记录在编目表的INDEXAUTH下。
授予特权的命令为:
USER
GRANT CONTROL ON INDEX index_name TOGROUP
PUBLIC
Authorization_name
5、软件包权限
软件包权限有:CONTROL、EXECUTE和BIND权限。
授予特权的命令为:
BIND
GRANTCONTROLON PACKAGE package_name
EXECUTE
TOUSER
GROUP
PUBLIC
authorization_name
三、上机实验
1、创建如下三个基表:
S (S#,SNAME,AGE,SEX) 对应的中文为:
[学生 (学号,姓名,年龄,性别)]
SC (S#,C#,GRADE) 对应的中文为:
[学习(学号,课程号,成绩)]
C(C#,CNAME,TEACHER) 对应的中文为:
[课程(课程号,课程名,任课教师)]
2、创建视图
根据表S、表C和表SC创建视图S_C_SC,使其具有如下内容:学号,姓名,课程名,成绩
3、创建一个基表,并将SELECT,UPDATE,DELETE,INSERT权限授予另一用户。
第三章 数据插入、删除和修改
一、上机目的
1、掌握数据插入命令
2、掌握数据删除命令
3、掌握数据修改命令
二、预备知识
1、数据插入
一个基表创建好后,可以向基表中插入数据了。如向基表PERS中插入数据命令为
INSERT INTO PERS
VALUES(12,’Harris’,20,’Sales’,5,18000,1000,’1950-1-1’);
INSERT INTO PERS (NAME,JOB,ID)
VALUES (’Swagerman’,’Prgmr’,500),
(‘Limoges’, ’Prgmr’, 510),
(‘Li’, ’Prgmr’, 520)
INSERT INTO PERS (ID, NAME, DEPT, JOB, YEARS, SALARY)
SELECT ID ,NAME, DEPT, JOB, YEARS, SALARY
FROM STAFF
WHERE DEPT = 38
从上述三例可以看出,如果向基表中所有列都插入值时,不必将列名写出(一个有经验的程序员在存储过程中,一般不采用这种方式,因为基表的修改将导致本存储过程的失效);一个插入命令可以插入多行数据;可以将其他基表的数据插入本基表中。
2、数据修改
使用UPDATE语句可以修改表或视图中的数据。一个UPDATE语句中指定表的行,按WHERE子句中搜索条件为真时,用SET子句对要修改的行进行更新。如UPDATE语句中没有WHERE子句,则对该表的每行用SET子句更改。
SET子句可以包含一个或多个变元,每个变元是列名。其值由等号右边计算求得的值赋予。等号右边可以是表达式、查询、NULL和DEFAULT。下面利用UPDATE语句的例子是对ID为410的雇员信息的修改:
UPDATE PERS
SET JOB = ‘Prgmr’ , SALARY = SALARY + 300
WHERE ID = 410
在更新时,等号右边求值必须在更新之前完成。
UPDATE 语句的目标是表或视图。在更新一个视图时,会影响视图的基表。当然,在更新视图时,直接与视图对应的底层表之列也被更新。
用UPDATE 语句去说明一个更新时,有可能侵犯某些约束,如检验约束或有关集成约束(在第六章讨论)。在执行UPDATE语句过程中,出现任何错误,语句不作任何修改,回滚重新执行。
在UPDATE语句中,如WHERE子句或SET子句中有子查询,该子查询必须先求出结果后,才能对任何表进行更新。如在子查询中还包含正要更新的表时,称该UPDATE语句是自引用。在自引用中的UPDATE语句的全部子查询(甚至相关联子查询)将在修改前的原表中查找。
当一个列被UPDATE语句修改时,特别是那些唯一的索引列或主码列(在第六章中介绍),它们在修改后要求保证唯一性实施。这种情况下,有时会使UPDATE语句执行失败而回滚重做。因为,发生了暂时唯一性的破坏。如果这种暂时唯一性破坏是与修改排序有关,则UPDATE语句的成功或失败可以预测。如下面的例子,假设COL1是TAB1表的主码列,该列的值分别为1,2,3,4,5。用下列UPDATE语句:
UPDATE TAB1
SET COL1 = COL1 + 1
系统用主码值的升序对TAB1的各行进行更新,这语句执行将失败,因为对第1行修改是破坏了暂时唯一性,但是,如系统用主码的降序对TAB1各行进行修改,该UPDATE语句是成功的。
3、数据删除
DELETE 语句是为了在表或视图中,删除一行或多行内容。删除视图行时,会影响到视图基表相应行的删除。
删除语句比较简单:针对已给名的表中,按搜索条件为真的那些行,将它们从数据库的表中删除。如没有WHERE子句,即将整个表或视图进行删除。例如:删除雇员ID为120的雇员记录时,
DELETE FROM PERS
WHERE ID = 120
如在DELETE 语句的搜索条件中包含一个子查询,且子查询引用的表与将要删除的表相同,子查询先查完后再进行删除。这种删除称为自引用删除语句。
用删除语句说明删除的某行,有可能侵犯某些约束。如有关集成约束。在执行DELETE 语句过程中,遇到任何错误,它不作任何删除回滚重做。
当你删除一行时,你将删除整行,而不能删除部分列;若要删除一个定义的表和它下面的所有内容,用DROP TABLE 命令。
三、上机实习(利用第二章创建的基表和数据)
1、用INSERT 命令插入数据
基本表S的数据基表C的数据
S1WANG20MC2MATHSMA
S2LIU19MC4PHYSICSSHI
S3CHEN22MC3CHEMISTRYZHOU
S4WU19MC1DBLI
S5LOU21FC5OSWEN
S8DONG18F
基本表SC的数据(空格为未选修)
C# S#S1S2S3S4S5S8
C1808590757090
C270NULL8560NULL
C38595NULL8090
C490NULL70
C57065NULL
2、把C2课程的非空成绩提高10%
3、在SC表中删除课程名为PHYSICY的成绩的元组
4、在S和SC表中删除学号为S8的所有数据
第四章 数 据 查 询
一、上机目的
1、掌握SELECT语句的基本语法
2、熟练使用SELECT语句的各子句进行组合查询
二、预备知识
数据查询是最基本的数据操作,用一个SQL语句去完成数据库的信息检索称为查询,一个查询是在数据库内搜索能回答某个问题的一些表。这问题解答结果以行的集合形式给出,称为查询的结果集合。下面就先介绍一下数据库的简单查询。
1、选择列
用SELECT语句可以从一个表中选择特定的列,在各列之间用分号隔开。如:
SELECT DEPTNAME,DEPTNUMB
FROM ORG
其结果为:
DEPTNAMEDEPTNUM
-------------------------------
Head Office10
New England15
Mid Atlantic20
South Atlantic38
Great Lakes42
Plains51
Pacific66
Mountain84
如果使用*则可将表中所有的列都选择出来,下面的例子为将ORG表中的所有列和行都选择出来。
SELECT *
FROM ORG
结果为:
DEPTNUMBDEPTNAMEMANAGERDIVISIONLOCATION
10Head Office160CorporateNew Work
15New England50EasternBoston
20Mid Atlantic10EasternWashington
38South Atlantic30EasternAtlanta
42Great Lakes100MidwestChicago
51Plains140MidwestDallas
66Pacific270WesternSan Francisco
84Mountain290WesternDenver
2、选择行
从一个表中选择行,须在SELECT 语句后加WHERE 子句,用以表明选择条件,多个条件之间用AND相连。如:
SELECT DEPT,NAME,JOB
FROM STAFF
WHERE JOB =’Clerk’
AND DEPT = 20
其结果为:
DEPT NAME JOB
-------- ---------------- -------
20 James Clerk
20 Sneider Clerk
当要判断一个列值是否为NULL时,应使用谓词IS NULL,IS NOT NULL 来判断。如:
SELECT ID,NAME
FROM STAFF
WHERE COMM IS NULL
其结果为:
ID NAME
-------------------------------
10Sanders
30Marenghi
50Hanes
100Plotz
140Fraye
160Molinare
210Lu
240Daniels
260Jones
270Lea
290Quill
3、行排序
如果你想要得到的信息按一定的顺序排列,就要使用ORDER BY子句来将一列或多列的信息按其值排序。下面的一个例子是将部门为84员工按工龄从大到小显示出来:
SELECT NAME,JOB,YEARS
FROM STAFF
WHERE DEPT = 84
ORDER BY YEARS
其结果为如下:
NAMEJOBYEARS
-------------------------
DavisSales5
GafneyClerk5
EdwardsSales7
QuillMgr10
ORDER BY 默认为按从大到小排序,相当于ASC省略了,若要从小到大排序,则要使用DESC例如:
SELECT NAME,JOB,YEARS
FROM STAFF
WHERE DEPT = 84
ORDER BY YEARS DESC
其结果正好和上次查询结果相反,上次查询第一行为最后一行。
4、去掉查询结果中相同的行
使用SELECT语句进行查询时,可能返回多条重复的信息,去掉这些重复的信息要在SELECT语句中加上DISTINCT选项,例如
SELECT DISTINCT DEPT,JOB
FROM STAFF
WHERE DEPT 30
ORDER BY DEPT,JOB
其结果为:
DEPT JOB
-------- -----
10Mgr
15Clerk
15Mgr
15Sales
20Clerk
20Mgr
20Sales
5、用表达式去计算值
表达式就是SELECT语句中的一个计算式或函数,下面的例子是计算部门为38的每一个员工获得500元奖金后的薪水:
SELECT DEPT,NAME,SALARY+500
FROM STAFF
WHERE DEPT = 38
ORDER BY 3
其结果为:
DEPTNAME3
---------------------------------
38Abrahams12509.75
38Naughton13454.75
38Quigley17308.30
38Marenghi18006.75
38O’Brien18506.00
6、别名
在SELECT 语句中用AS从句给一个表达式取个有意义的名字,使它更能表达其真实含义。例如:下例中,显示工资加奖金小于13,000的职员,SALARY+COMM的列标题为PAY:
SELECT NAME,JOB,SALARY+COMM AS PAY
FROM STAFF
WHERE (SALARY+COMM) 13000
ORDER BY PAY
结果为:
NAMEJOBPAY
-----------------------------------------
YamaguchiClerk10581.50
BurkeClerk 11043.50
ScouttenClerk11592.80
AbrahamsClerk12246.25
KermischClerk12368.60
NganClerk12714.80
7、从多个表中选择数据
你可以从多个表中选择数据来生成一个报表,这类方式通常称为连接。例如,你可以将STAFF和ORG中的数据连接起来生成一个新的表,要连接两个表,将你要选择的列放在FROM子句中,表的名字放在FROM子句中,要选择的条件放在WHERE子句中,WHERE子句是可选的。
下面的例子是将每一个部门经理和一个部门名联系起来,由于员工信息存储在STAFF表中,而部门信息存储在ORG表中,从STAFF和ORG表中选取NAME和DEPTNAME字段,选择条件是MANAGER列值与ID列值相等,则相应的查询如下:
SELECT DEPTNAME,NAME
FROM ORG,STAFF
WHERE MANAGER = ID
其结果为:
DEPTNAMENAME
----------------------------------
Mid AtlanticSanders
AtlanticMarenghi
South AtlanticHanes
New EnglishHanes
Great Lakes Plotz
Plains Fraye
Head Office Molinare
Pacific Lea
Mountain Quill
8、子查询
如将一个SELECT语句放在另一个SELECT语句的WHERE子句内作为其查询的条件,则称为则该SELECT语句称为另一个SELECT语句的子查询。
例如,下面的语句从ORG表中选择DEVISION 和 LOCATION,雇员的ID在STAFF表中其值为280。
SELECT DIVISION, LOCATION
FROM ORG
WHERE DEPTNUMB =(SELECT DEPT
FROM STAFF
WHERE ID = 280)
在处理这种查询时,DB2首先计算出子查询的值。本例由于ID为280的雇员在66部门,因此查询结果为66。最后的结果是从ORG表中选出DEPTNUMB为66的行,结果为:
DIVISION LOCATION
--------------------- -------------------
Western San Francisco
子查询将在第五章节中详细讨论。
9、函数的使用
这部分简要地介绍一下以后章节中将要使用的函数。一个数据库函数,就是将一串数据作为输入,得到返回值。可分为内部函数和用户自定义函数。DB2通用数据库具有很多系统函数和预装的自定义函数。你可以在SYSIBM模式下找到系统函数,在SYSFUN模式下找到预装的用户自定义函数。其中SYSIBM和SYSFUN是系统保留的模式。内部函数和预装的用户自定义函数不可能满足用户的所有需求,因此用户可以根据应用的特殊需要开发自定义的函数,下面将介绍这些函数。
1)、列函数
列函数根据处理列值的集合生成一个唯一的结果。下面是几个列函数的例子。若需要全部列函数的列表请参考SQL Reference
AVG 从选出的列集合中将其值相加后除以该集合中值的个数,即计算选出列值的平均值。
COUNT 返回所选集合中行的个数。
MAX 返回所选集合中的最大值
MIN 返回所选集合中的最小值
下面的语句从STAFF表中选出SALARY的最大值
SELECT MAX(SALARY)
FROM STAFF
其结果为22959.20
下面的例子是查询雇员中的NAME和SALARY其收入高于公司雇员的平均收入但其工作年限却小于公司雇员的平均工作年限。
SELECT NAME,SALARY
FROM STAFF
WHERE SALARY > ( SELECT AVG(SALARY) FROM STAFF)
AND YEARS (SELECT AVG(YEARS) FROM STAFF)
结果为:
NAME SALARY
------------ -------------
Marenghi 17506.75
Daniels 19260.25
Gonzales 16858.20
2)、纯量函数
纯量函数是输入一个值后返回另外一个值的操作。下面的DB2通用数据库提供的几个纯量函数的例子。
ABS 返回一个数字的绝对值
HEX 返回一个十进制数的16进制形式
LENGTH 返回所带参数的字节数
YEAR 从日期型的参数中分离出年的部分。
需要详细清单和介绍纯量函数请参考SQL Reference。
下面的例子从ORG表中返回部门的名称,及其对应的长度
SELECT DEPTNAME, LENGTH(DEPTNAME)
FROM ORG
其结果为:
DEPTNAME 2
--------------------
Head Office11
New England11
Mid Atlantic12
South Atlantic14
Great Lakes11
Plains 6
Pacific 7
Mountain 8
3)、用户自定义函数
用户自定义函数将在函数部分详细讨论。
10、分组
DB2通用数据库具有按表特定的列进行分析的能力。你可以用GROUP BY 将行按定义进行分组。在其最简单的形式中,一个组包含的列称为分组列(grouping columns)。在SELECT 语句中的列名必须是分组列或列函数。列函数为每一个由GROUP BY定义的组返回一个函数值。下面的例子是列出每一部门的最高薪水。
SELECT DEPT, MAX(SALARY) AS MAXIMUM
FROM STAFF
GROUP BY DEPT
其结果为:
DEPT MAXIMUM
-------- ---------------
1022959.20
1520659.80
2018357.50
3818006.00
4218352.80
5121150.00
6621000.00
8419819.00
注意MAX(SALARY)是指由GROUP BY语句定义每一部门的最大值,而不是整个公司的最大值。
11、用GROUP BY 的WHERE语句
在分组查询中可以用标准的WHERE语句在组的生成和组函数的计算之前来排除不符合要求的行,但你必须将WHERE语句放在GROUP BY语句之前。例如:
SELECT WORKDEPT, EDLEVEL, MAX (SALARY) AS MAXIMUM
FROM EMPLOYEE
WHERE HIREDATE > ‘1979-01-01’
GROUP BY WORKDEPT, EDLEVEL
ORDER BY WORKDEPT, EDLEVEL
其结果为:
WORKDEPT EDLEVEL MAXIMUM
----------------------------------------------------------
D111718270.00
D211527380.00
D211636170.00
D211728760.00
E111215340.00
E211426150.00
注意:在SELECT 语句中出现的列在GROUP BY 语句中也出现。如果两者不一致将会出错。GROUP BY 语句返回每一行都是WORKDEPT和EDLEVEL的唯一组合。
12、用HAVING语句 的GROUP BY语句
你可以按分组条件对记录进行分组,但是要将分组后的记录进行选择时,就要在GROUP BY 语句之后使用HAVING 语句。一个HAVING 语句可以包含一个或多个谓词,由AND 或 OR 相连。与组的一个属性AVG(SALARY)比较的谓词有:
1)、另一个属性
例如: HAVING AVG(SALARY) > 2*MIN(SALARY)
2)、常量
例如: HAVING AVG(SALARY) > 20000
下面的查询是有四个以上的雇员的部门中找到该部门薪水的最大值和最小值。
SELECT WORKDEPT, MAX(SALARY) AS MAXIMUM, MIN(SALARY) AS MINIMUM
FROM EMPLOYEE
GROUP BY WORKDEPT
HAVING COUNT(*) > 4
ORDER BY WORKDEPT
结果为:
WORKDEPT MAXIMUM MINIMUM
------------------- ----------------- ---------------
D11 32250.00 18270.00
D21 36170.00 17250.00
E11 29750.00 15340.00
在一个查询中使用HAVING语句但不使用GROUP BY语句是可行的(不常使用),在这种情况下,DB2将整个表当作一个组来看待。由于整个表被看成一个组,你最多只能得到一行结果。如果HAVING对整个表而言条件为真,将返回结果,否则,没有行被返回。
三、上机实验(利用第二章创建的基表和数据)
1、检索学习课程号为C2的学生学号与姓名
2、检索选修课程名为MATHS的学生学号与姓名
3、检索不学C2课程的学生姓名与年龄
4、检索学习全部课程的学生姓名
5、检索课程C1,C2,C3,C4,C5的最高分和最低分
第五章 高效查询
一、上机目的
1、熟悉并掌握纯量子查询、CAST表达式、CASE表达式以及表表达式的运用
2、熟悉并掌握关联名字、关联子查询、集合操作、谓词和连接在查询中的运用
二、预备知识
DB2通用数据库提供了强大的查询功能,下面将介绍一些更复杂的查询的方法。
1、纯量子查询
一个表达式,表示一个纯量值,它由基本部件组成,如列名、常数、宿主变量、函数、专用寄存器。在DB2通用数据库中,在可使用表达式地方也可使用返回一个纯量值的子查询,它也可看作为具有一列的一行。当一个子查询可用于使用纯量的地方,该子查询称为纯量子查询(scalar subquery)。如果一个纯量子查询返回多行或多列,将产生一个错误。如果一个纯量子查询没有返回行,其结果解释为空值,在这种情况下,不引起错误,除非在上下文中,由于某种原因不允许使用空值。在DB2 version 1中允许用的许多子查询,都是纯量子查询。然而,由DB2 version2支持正交性新标准后,允许纯量子查询可在V1原不可接受的地方使用它。
下面的例子列出薪水大于所有雇员平均薪水的雇员的名字:
SELECT LASTNAME,FIRSTNAME
FROM EMPLOYEE
WHERE SALARY > (SELECT AVG(SALARY)
FROM EMPLOYEE )
下面的例子从两个不同的表中找到雇员的平均薪水
SELECT AVG(SALARY) AS “Average_Employee”,
(SELECT AVG(SALARY) AS “Average_Staff”
FROM STAFF)
FROM EMPLOYEE
2、CAST表达式
CAST表达式是将一种数据类型转换成另一种数据类型的值的处理,例如将一整数值转换十进制数据类型数据。为了保证转换成功,目标数据数据类型必须适当地定义,包含它的长度、精度和小数部分位数。最安全是显式地指定类型特性,如下列例子:
CAST (C1+C2 AS DECIMAL(8,2))
CAST (NAME || ADDRESS AS VARCHAR(255))
下面是CAST表达式的有效使用
原数据类型目标数据类型
Smallint, Integer, Decimal, DoubleSmallint, Integer, Decimal , Double
Char, Varchar, Long Varchar, ClobChar, Varchar, Long Varchar, Clob,Blob
Graphic, Vargraphic,Long Vargraphic, DbclobGraphic, Vargraphic, Dblob, Long Vargraphic, Blob
Char, VarcharSmallint, Integer, Decimal, Date,Time,Timestamp, Vargraphic
Smallint, Integer, DecimalChar
Date, Time, TimestampChar, Varchar
DateDate
TimeTime
TimestampDate,Time,Timestamp
BlobBlob
CAST表达式允许使用NULL,但在V1中是不允许的。
CAST语句可将一个长字符串截掉,如EMP_RESUME表中的RESUME的列为CLOB(5K),如果只想使该字段的前370字符如果是以ASCII码格式存储在EMP_RESUME表中,使用如下查询:
SELECT EMPNO,CAST(RESUME AS VARCHAR(370))
FROM EMP_RESUME
WHERE RESUME_FROMAT = ”ascii’
你将得到一个警告:大于370个字符的部分将被截去。
3、CASE表达式
在数据库设计时,数据库设计者对一数据库列的值经常通过压缩编码法来节省空间,但在从该列检索值时,其应用总希望显示该值的真正含义而不愿以压缩编码方式表示。利用DB2通用数据库强有力的新特性,CASE表达式可以完成这样处理,类似于一些编程语言中的CASE表达式的概念。
下面的例子是将ORG表中的DEPTNAME列表示成更有意义的显示形式,其查询为:
SELECT DEPTNAME,
CASE DEPTNUMB
WHEN 10 THEN ‘Marketing’
WHEN 15 THEN ‘Research’
WHEN 20 THEN ‘Development’
WHEN 38 THEN ‘Accounting’
ELSE ‘Sales’
END AS FUNCTION
FROM ORG
其结果为:
DEPTNAME FUNCTION
--------------------- -------------------
Head OfficeMarketing
New EnglandResearch
Mid AtlanticDevelopment
South AtlanticAccounting
Great LakesSales
Plains Sales
Pacific Sales
Mountain Sales
CASE表达式可以防止被0除这一意外的发生,下面的例子避免这种情况:
SELECT LASTNAME, WORKDEPT FROM EMPLOYEE
WHERE (CASE
WHEN BONUS+COMM = 0 THEN NULL
ELSE SALARY / (BONUS + COMM)
END)> 10
利用CASE表达式可以在一个查询语句中计算表中一列的一个子集的和于表中所有该列的和的比例,如果没有CASE语句,则至少要分两步计算才能达到要求。
下面的例子是计算部门为20的薪水总和与所有部门薪水总和的比例:
SELECT CAST(CAST(SUM(CASE
WHEN DEPT = 20 THEN SALARY
ELSE 0
END ) AS DECIMAL(7,2))/
SUM(SALARY) AS DECIMAL(3,2))
FROM STAFF
该结果为0.11。CAST函数确保了保留的结果的精度。
你也可以利用CASE表达式来实现调用函数的功能,例如:
CASE
WHEN X 0 THEN –1
WHEN X= 0 THEN 0
WHEN X 0 THEN 1
END
其功能与在SYSFUN模式下用户自定义函数SIGN相同。在DB2通用数据库中,有2个函数类似于某种特殊的CASE表达式,其名字为NULLIF 和 COALESCE。
NULLIF函数是CASE表达式的缩写表示。如果它的第一个参数等于它的第二个参数时返回一个空值,否则返回它的第一个参数。该函数在指定一值(如-1)作为NULL的编码时是很有用的,例如NULLIF(SALARY,-1)为下列表达式的缩写:
CASE
WHEN SALARY = -1 THEN NULL
ELSE SALARY
END
COALESCE 函数有可变参数数目,它返回第一个具有非空值的参数,如果全部参数为空值(NULL),其结果为空值。在调用COALESCE中传送的全部参数必须有相兼容的数据类型。但不必要相同,例如参数可以是各种数值的数据类型,如Integer,Decimal和Float,调用该函数的结果数据类型为输入数据类型中的位数最大者,例如调用COALESCE(x,y,z),其中x是一个空整数,y是十进制5.7,z是Double类型的空值,其结果的数据类型是Double,值是5.7。对于COALESCE函数如何处理数据类型更完善的说明请参考SQL REFERENCE。
例如假设有如下一个表OFFICERS,下列的查询:
SELECT NAME, COALESCE(RANK,TITLE) AS RANK _OR_TITLE
FROM OFFICERS
WHERE STATUS IN(1,2,3)
在该查询中,COALESCE(RANK,TITLE)表达式可认为是下列CASE表达式:
CASE
WHEN RANK IS NOT NULL THEN RANK
ELSE TITLE
END
4、表表达式(TABLE EXPRESSION)
在先前章节中的子查询都是用于纯量的地方。但实际上子查询也可返回一个表,有多行多列组成,这样的子查询称为表表达式,可在FROM子句中使用。
表表达式是临时的,仅在处理当前SQL语句时有效。它们不像VIEW一样可被授权用户共享,但它比VIEW具有更大的灵活性。
表表达式可分为嵌套表表达式和公共表表达式。
1)、嵌套表表达式
一个嵌套表表达式是一个临时的VIEW,定义是嵌套在主查询的FROM子句中。下面的查询是用一个嵌套的表表达式找到总的平均工资,教育级别和工龄,其中教育级别大于16。
SELECT EDLEVEL,HIREYEAR,DECIMAL(AVG(TOTAL_PAY),7,2)
FROM (SELECT YEAR(HIREDATE)AS HIREYEAR,EDLEVEL,
SALARY+BONUS+COMM AS TOTAL_PAY
FROM EMPLOYEE
WHERE EDLEVEL > 16) AS PAY_LEVEL
GROUP BY EDLEVEL, HIREYEAR
ORDER BY EDLEVEL, HIREYEAR
其结果为:
EDLEVEL HIREYEAR 3
------------- --------------- --------------
17 1967 28850.00
17 1973 23547.00
17 1977 24430.00
17 1979 25896.00
18 1965 57970.00
18 1968 32827.00
18 1973 45350.00
18 1976 31294.00
19 1958 51120.00
20 1975 42110.00
这个查询首先使用了一个嵌套表表达式首先将HIREDATE字段中的年份分离出来以便后面的GROUP BY 语句中使用。由于你可能使用不同的EDLEVEL来执行类似的查询,建立VIEW就不方便了。
在此例中使用了内部函数DECIMAL。DECIMAL返回一个带分数的数字或字符串,若要了解函数更详细的信息,请参考SQL Reference。
2)、公共表表达式
公共表表达式在SQL语句中由一个WITH子句开头,其WITH子句的定义类似于视图的定义。一个公共表表达式定义了一个或多个临时视图,其仅在处理当前SQL语句期间有效。在WITH子句中定义的临时视图可经常在语句中使用,不管如何使用它们,每一个临时视图仅计算一次,所以不可能在SQL语句看到不一致的数据。若使用嵌套表表达式或VIEW,语句的结果将每次都生成一次,这样会可能得到不一致的数据。
下面的例子列出了所有公司的雇员,其条件是:教育级别大于16,工龄相同、教育级别相同但工资却比这些人的平均工资低。实现上述功能的查询如下:
①
WITH
PAYLEVEL AS
(SELECT EMPNO,YEAR(HIREDATE) AS HIREYEAR,EDLEVEL,
SALARY+BONUS+COMM AS TOTAL_PAY
FROM EMPLOYEE
WHERE EDLEVEL > 16),
②
PAYBYED (EDUC_LEVEL,YEAR_OF_HIRE,AVG_TOTAL_PAY) AS
(SELECT EDLEVEL, HIREYEAR, AVG(TOTAL_PAY)
FROM PAYLEVEL
GROUP BY EDLEVEL, HIREYEAR),
③
SELECT EMPNO, EDLEVEL, YEAR_OF_HIRE,
TOTAL_PAY, DECIMAL (AVG_TOTAL_PAY, 7, 2)
FROM PAYLEVEL, PAYBYED
WHERE EDLEVEL=EDUC_LEVEL
AND HIREYEAR = YEAR_OF_HIRE
AND TOTAL_PAY AVG_TOTAL_PAY
其中:
①是一个公共表表达式,其名字为PAYLEVEL。这个结果表包括这个雇员受雇的年份,这个雇员的所有所得(SALARY+BONUS+COMM),和他的教育级别。当然所有记录其教育级别大于16。
②是一个以PAYBYED(PAY BY EDUCATION)命名的公共表表达式。它使用了先前定义的公共表表达式PAYLEVEL,选出了在同一教育级别、在同一年聘用的雇员的EDLEVEL, HIREYEAR, AVG(TOTAL_PAY)并分别以不同的名字(如EDUC_LEVEL)。
③最后,我们得到了最终结果。两个表的结合(PAYLEVEL,PAYBYED)就实现列出教育级别大于16,工龄相同、教育级别相同但工资却比这些人的平均工资低的记录。结果如下:
EMPNO EDLEVEL YEAR_OF_HIRE TOTAL_PAY 5
--------- ------------ ----------------------- --------------- -------
000210 17 1979 20132.00 25896.50
5、关联名字(Correlation Names)
关联名字是一个对象用于区分多个用户的标识,。这个关联名字出现在查询语句的FROM子句和UPDATE、DELETE语句的第一个语句中。它与一个表、视图或一个嵌套表表达式联系在一起。
例如,在子句FROM STAFF S,ORG O 分别为STAFF、ORG建立一个关联名字S和O。
SELECT NAME,DEPTNAME
FROM STAFF S,ORG O
WHERE O.MANAGER=S.ID
一旦你定义了一个关联名字,你就得用这一关联名字来标识这个对象。例如上面的例子中若使用ORG.MANAGER=STAFF.ID,则此查询将会失败。
使用关联名字,你可以为一个对象生成一个副本。如果你要将一个表进行自身比较,这非常有用。在下面的例子中,EMPLOYEE表与自身比较找到各个雇员的经理,显示不是DESIGNER的雇员,其经理的名字和部门号。
SELECT E2.FIRSTNME, E2.LASTNAME,
E2.JOB, E1.FIRSTNME, E1.LASTNAME, E1.WORKDEPT
FROM EMPLOYEE E1 , EMPLOYEE E2
WHERE E1.WORKDEPT= E2.WORKDEPT
AND E1.JOB = ‘MANAGER’
AND E2.JOB >’MANAGER’
AND E2.JOB >’DESIGNER’
结果为:
FIRSTNMELASTNAMEJOBFIRSTNMELASTNAMEWORKDEPT
---------------------------------------------------------------------------------------------
DOLORESQUINTANAANALYSTSALLYKWANC01
HEATHER NICHOLLS ANALYSTSALLYKWANC01
JAMESJEFFERSONCLERKEVAPULASKID21
MARIAPEREZCLERKEVAPULASKID21
SYBILJOHNSONCLERKEVAPULASKID21
DANIELSMITHCLERKEVAPULASKID21
SALVATOREMARINOCLERKEVAPULASKID21
ETHELSCHNEIDEROPERATOREILEENHENDERSONE11
MAUDESETRIGHTOPERATOREILEENHENDERSONE11
PHILIPSMITHOPERATOREILEENHENDERSONE11
JOHNPARKEROPERATOREILEENHENDERSONE11
RAMLALMEHTAFIELDREPTHEODORESPENSERE21
JASONGOUNOTFIELDREPTHEODORESPENSERE21
WINGLEEFIELDREPTHEODORESPENSERE21
6、关联子查询
关联子查询是指引用任何先前的使用过的表的子查询。我们也可以说该子查询有一个到主查询中的表关联引用(correlated reference)。
下面的例子列出了A00的部门中薪水高于本部门平均薪水的雇员的号码和名字,但不是一个关联子查询:
SELECT EMPNO,LASTNAME
FROM EMPLOYEE
WHERE WORKDEPT = ‘A00’
AND SALARY > (SELECT AVG(SALARY)
FROM EMPLOYEE
WHERE WORKDEPT = ‘A00’)
如果你想知道每一部门的平均薪水,则子查询中需要对每一部门计算一次。列出每部门中薪水高于本部门平均薪水的雇员的雇员号、雇员名字和部门号,可利用SQL语句中关联子查询功能,其实现如下:
SELECT E1.EMPNO,E1.LASTNAME,E1.WORKDEPT
FROM EMPLOYEE E1
WHERE SALARY > (SELECT AVG(SALARY)
FROM EMPLOYEE E2
WHERE E2.WORKDEPT = E1.WORKDEPT)
ORDER BY E1.WORKDEPT
7、查询中的集合操作
在DB2通用数据库中可以用集合操作来合并查询结果,用谓词来建立复杂的条件语句。
UNION、EXCEPT和INTERSECT集合操作符可以将两个或两个以上的外部查询合并为一个查询。每个查询由这些集合操作符相连,各个查询执行后再将每个结果合并。根据不同的操作符,产生不同的结果。
1)、UNION操作符
UNION操作符将两个查询的结果合并,但删去合并结果中相同的行。当ALL使用时(即UNION ALL),相同的行不删去。下面使用UNION的例子,其结果将返回工资大于21,000美元或具有管理职责并且工作少于8年。
①
SELECT ID,NAME FROM STAFF WHERE SALARY > 21000
UNION
②
SELECT ID,NAME FROM STAFF WHERE JOB = ’Mgr’ AND YEARS 8
ORDER BY ID
①的结果为
ID NAME
140Fraye
160Molinare
260Jones
②的结果为
IDNAME
10Sanders
30Marenghi
100Plotz
140Fraye
160Molinare
240Daniels
数据库管理器将合并这两个查询的结果,删去返回结果中相同的行,并按ID排序。
ID NAME
10Sanders
30Marenghi
100Plotz
140Fraye
160Molinare
240Daniels
260Jones
2)、EXCEPT 操作符
EXCEPT操作符选取第一个表的查询结果,除去第二个表中相同的查询结果。例如在下例中使用EXCEPT操作符,查询结果将返回每月挣21,000美元但没有经理职位或工作至少有8年。
SELECT ID,NAME FROM STAFF WHERE SALARY > 21000
EXCEPT
SELECT ID,NAME FROM STAFF WHERE JOB=’Mgr’ AND YEARS 8
其结果为:
ID NAME
----- -------
260Jones
3)、INTERSECT 操作符
INTERSET操作符选取第一个表的查询结果和第二个表的查询结果的交集。若使用INTERSECT ALL,则两个表的相同的查询结果不删除,反之将删除。在下例中使用INTERSECT操作符,查询结果将返回每月挣21,000美元且具有经理职位或工作至少有8年。
SELECT ID,NAME FROM STAFF WHERE SALARY > 21000
INTERSECT
SELECT ID,NAME FROM STAFF WHERE JOB=’Mgr’ AND YEARS 8
其结果为:
ID NAME
----- -------
140Fraye
160Molinare
8、谓词的使用
在DB2通用数据库中,谓词的使用可以将选择满足条件的的行。
1)、IN谓词
用谓词IN来将一个值与几个值进行比较。例如:
SELECT NAME
FROM STAFF
WHERE DEPT IN (20,15)
这个例子等价于:
SELECT NAME
FROM STAFF
WHERE DEPT=20 OR DEPT=15
当一个子查询返回一个值的集合时,你可以用IN或NOT IN,下面的查询将列出负责MA2100和OP2012项目的雇员的姓:
SELECT LASTNAME
FROM EMPLOYEE
WHERE EMPNO IN
(SELECT RESPEMP
FROM PROJECT
WHERE PROJNO = ‘MA2100’
OR PROJNO = ’OP2012’)
子查询只计算一次,其结果将直接替换到外层查询。例如上面子查询选择雇员号为10和330,则外层查询的WHERE子句为
WHERE EMPNO IN(10,330)
2)、BETWEEN谓词
用谓词BETWEEN将一个值与一个值的范围进行比较。这个范围有BETWEEN谓词确定。下面的例子是找到收入在10,000美元到20,000美元的雇员:
SELECT LASTNAME
FROM EMPLOYEE
WHERE SALARY BETWEEN 10000 AND 20000
等价于:
SELECT LASTNAME
FROM EMPLOYEE
WHERE SALARY >=10000 AND SALARY =20000
下面的例子找到收入少于10,000美元或大于20,000美元的雇员:
SELECT LASTNAME
FROM EMPLOYEE
WHERE SALARY NOT BETWEEN 10000 AND 20000
3)、LIKE谓词
使用LIKE谓词来查找一定模式的字符。模式中可以有下划线和百分号。其中下划线代表任何一个字符,百分号代表一个具有0个或多个字符的字符串,其它字符代表它本身。
下面的例子选取姓名为七个字符长且以字母 ‘S’打头的雇员。
SELECT NAME
FROM STAFF
WHERE NAME LIKE ‘S------‘
下面的例子选取姓名不是以字母 ‘S’打头的雇员。
SELECT NAME
FROM STAFF
WHERE NAME NOT LIKE ‘S%‘
4)、EXISTS谓词
你可以用一个子查询来测试满足一定条件的行是否存在。在这种情况下,子查询通过EXISTS 或者NOT EXISTS来与外部查询相联系。
当一个子查询与外部查询用EXISTS谓词相连时,子查询并不返回值。如果子查询包含一行或多行则EXISTS谓词为真,否则为假。
EXISTS谓词通常用于关联子查询,下面的例子列出与PROJECT表没有关系的部门号和部门名字。
SELECT DEPTNO,DEPTNAME
FROM DEPARTMENT X
WHERE NOT EXISTS
(SELECT *
FROM PROJECT
WHERE DEPTNO = X.DEPTNO)
5)、Quantified谓词
使用Quantified谓词将一个值与一串值进行比较。用ALL、SOME、ANY去限定比较结果。如:
expression > ALL (fullselect)只有当expression大于fullselect返回值中的任何一个值时,Quantified谓词为真。如果fullselect没有返回值时,Quantified谓词也为真。〈〉ALL的Quantified谓词与NOT IN 谓词等同。
下面的例子使用一个子查询和一个> ALL比较比所有经理挣得多的雇员的姓名和职业。
SELECT LASTNAME,JOB
FROM EMPLOYEE
WHERE SALARY > ALL
(SELECT SALARY
FROM EMPLOYEE
WHERE JOB=’MANAGER’)
expression > ANY(fullselect)
表示当expression大于fullselect中返回值的任何一个该谓词为真。如果fullselect没有返回值,则该谓词为假。=ANY与谓词IN等同。
expression > SOME(fullselect)
SOME 是 fullselect 的同义词。
若需要了解更多的谓词和操作符的信息,请参阅SQL Reference。
9、连接(Joins)
如果在单个表上浏览,用简单的SQL语句可以找到满足搜索条件的行。但是,要查询的问题常常涉及到多个表。这类问题的查询表示称为连接(join)。一个连接查询,FROM子句后不只是一个表,而是查询所涉及的所有表连接起来,每个表名用逗号分隔。抽象地说,FROM子句所列的表的行均为可成为系统各种组合。对每种组合还可应用到搜索条件上。在一个连接查询中,常常需要对连接行指定某种关系。以下面两表为例。它们不在DB2所附带的样例数据库中,但本例中特别有用。
表SAMP_PROJECT
NAMEPROJ
HaasAD3100
ThompsonPL2100
WalkerMA2112
LutzMA2111
表SAMP_STAFF
NAMEJOB
HassPERS
ThompsonMANAGER
LucchessiSALESERP
NichollsANAALYST
LutzMA2111
下例产生了两个表的交叉乘积。如果不指定一个连接条件,则其结果为所有现行表的组合。
SELECT SAMP_PROJECT.NAME,
SAMP_PROJECT.PROJ, SAMP_STAFF.NAME, SAMP_STAFF.JOB
FROM SAMP_PROJECT, SAMP_STAFF
结果为:
NAMEPROJNAMEJOB
------------------------------------------------------------------------
HaasAD3100HassPERS
ThompsonPL2100HassPERS
WalkerMA2112HassPERS
LutzMA2111HassPERS
HaasAD3100ThompsonMANAGER
ThompsonPL2100ThompsonMANAGER
WalkerMA2112ThompsonMANAGER
LutzMA2111ThompsonMANAGER
HaasAD3100LucchessiSAALESREP
ThompsonPL2100LucchessiSAALESREP
WalkerMA2112LucchessiSAALESREP
LutzMA2111LucchessiSAALESREP
HaasAD3100NichollsANALYST
ThompsonPL2100NichollsANALYST
WalkerMA2112NichollsANALYST
LutzMA2111NichollsANALYST
两个主要的连接为内连接和外连接。内连接只保持了满足连接条件的行的乘积。如果在一个表中存在满足条件的一行,但另一个表的一行信息不满足条件,这样的信息是不会出现在结果表中。
下面是两个表的内连接的例子。
SELECT SAMP_PROJECT.NAME,
SAMP_PROJECT.PROJ, SAMP_STAFF,SAMP_STAFF.JOB
FROM