您必须先与数据库连接,才能使用 SQL 语句来查询或操作该数据库。CONNECT 语句使数据库连接与用户名相关联。
例如,要连接 SAMPLE 数据库,在 DB2 命令行处理器中输入下列命令: CONNECT TO SAMPLE USER USERID USING PASSWORD
(确保选择服务器系统上有效的 USER 和 USING 值)。
在此示例中,USER 的值为 USERID,USING 的值为 PASSWORD。
下列信息告诉您连接成功: 数据库连接信息
数据库产品 = DB2/6000 6.0.0
SQL 权限 ID = USERID
本地数据库别名 = SAMPLE
通过 CONNECT 语句设置连接时,建立显式连接。在隐式连接中已设置缺省服务器。在此情况下可以使用 CONNECT,或开始发出语句,将自动建立连接。
一旦连接上,就可以开始操作数据库。有关隐式和显式连接的详情,参考 SQL Reference 中的 CONNECT 语句。
无论何时在任何示例中输入出错时,或者如果执行 SQL 语句期间出错,则数据库管理程序返回错误信息。错误信息由信息标识符、简要说明以及 SQLSTATE 组成。
SQLSTATE 是 DB2 系列产品的公共错误码。 SQLSTATE 符合 ISO/ANSI SQL92 标准。
例如,如果 CONNECT 语句中用户名或口令不正确,则数据库管理程序将返回信息标识符 SQL1403N 和 SQLSTATE 为 08004。该信息如下: SQL1403N 提供的用户名和/或口令不正确。 SQLSTATE=08004
可以通过输入一个问号(?),然后输入信息标识符或 SQLSTATE 来获取关于错误信息的更多信息: ? SQL1403N
或
? SQL1403
或
? 08004
注意:错误 SQL1403N 的说明中倒数第二行表明 SQLCODE为-1403。 SQLCODE 为产品特定错误码。以 N(通知)或 C(严重)结尾的信息标识符表示一个错误,并且具有负 SQLCODE。以 W(警告)结尾的信息标识符表示一个警告,并且具有正 SQLCODE。
使用 SELECT 语句从表中选择特定的列。在该语句中指定用逗号分隔的列名列表。此列表称为选择列表。
下列语句从 SAMPLE 数据库的 ORG 表中选择部门名称 (DEPTNAME) 和部门号 (DEPTNUMB):
SELECT DEPTNAME, DEPTNUMB
FROM ORG
上面语句产生下列结果:
DEPTNAME DEPTNUMB
-------------- --------
Head Office 10
New England 15
Mid Atlantic 20
South Atlantic 38
Great Lakes 42
Plains 51
Pacific 66
Mountain 84
通过使用星号 (*) 可从表中选择所有列。下一个示例列出 ORG 表中的所有的列和行:
SELECT *
FROM ORG
此语句产生下列结果: DEPTNUMB DEPTNAME MANAGER DIVISION LOCATION
-------- -------------- ------- ---------- -------------
10 Head Office 160 Corporate New York
15 New England 50 Eastern Boston
20 Mid Atlantic 10 Eastern Washington
38 South Atlantic 30 Eastern Atlanta
42 Great Lakes 100 Midwest Chicago
51 Plains 140 Midwest Dallas
66 Pacific 270 Western San Francisco
84 Mountain 290 Western Denver
要从表中选择特定行,在 SELECT 语句之后使用 WHERE 子句指定要选择的行必须满足的条件。从表中选择行的标准是搜索条件。
搜索条件由一个或多个谓词组成。谓词指定关于某一行是真或是假(或未知)的条件。可使用下列基本谓词在 WHERE 子句中指定条件:
谓词 |
功能 |
x = y |
x 等于 y |
x <> y |
x 不等于 y |
x < y |
x 小于 y |
x > y |
x 大于 y |
x <= y |
x 小于或等于 y |
x >= y |
x 大于或等于 y |
IS NULL/IS NOT NULL |
测试空值 |
在构造搜索条件时,要注意只对数字数据类型执行算术运算,并只在相容数据类型之间进行比较。例如,不能将字符串与数字进行比较。
如果正在基于字符值来选择行,则该值必须用单引号括起来(例如,WHERE JOB = 'Clerk'),并且输入的每个字符值必须与数据库中的完全一样。如果数据值在数据库中是小写的,而您用大写形式来输入它,则将不选择行。如果正在基于数字值来选择行,则该值不得用引号括起来(例如,WHERE DEPT = 20)。
下列示例只从 STAFF 表中选择部门 20 的行: SELECT DEPT, NAME, JOB
FROM STAFF
WHERE DEPT = 20
此语句产生下列结果: DEPT NAME JOB
------ --------- -----
20 Sanders Mgr
20 Pernal Sales
20 James Clerk
20 Sneider Clerk
下一示例使用 AND 来指定多个条件。可以指定任意多个条件。该示例从 STAFF 表中选择部门 20 中的 clerk:
SELECT DEPT, NAME, JOB
FROM STAFF
WHERE JOB = 'Clerk'
AND DEPT = 20
此语句产生下列结果: DEPT NAME JOB
------ --------- -----
20 James Clerk
20 Sneider Clerk
未在其中输入值且不支持缺省值的列中出现空值。将值特别设置为空值的地方也可以出现空值。空值只能在定义为支持空值的列中出现。在表中定义和支持空值在创建表中讨论。
使用谓词 IS NULL 和 IS NOT NULL 来检查空值。
下列语句列出佣金未知的雇员: SELECT ID, NAME
FROM STAFF
WHERE COMM IS NULL
此语句产生下列结果: ID NAME
------ ---------
10 Sanders
30 Marenghi
50 Hanes
100 Plotz
140 Fraye
160 Molinare
210 Lu
240 Daniels
260 Jones
270 Lea
290 Quill
值零与空值不相同。下列语句选择表中佣金为零的每个人: SELECT ID, NAME
FROM STAFF
WHERE COMM = 0
因为样本表中的 COMM 列中没有零值,所以返回的结果集为空。
下一个示例选择 STAFF 表中 YEARS 的值大于 9 的所有行: SELECT NAME, SALARY, YEARS
FROM STAFF
WHERE YEARS > 9
此语句产生下列结果: NAME SALARY YEARS
--------- --------- ------
Hanes 20659.80 10
Lu 20010.00 10
Jones 21234.00 12
Quill 19818.00 10
Graham 21000.00 13
您可能想要信息按特定次序返回。使用 ORDER BY 子句将信息按一个或多个列中的值进行排序。
下列语句显示部门 84 中按雇用年数排序的雇员: SELECT NAME, JOB, YEARS
FROM STAFF
WHERE DEPT = 84
ORDER BY YEARS
此语句产生下列结果: NAME JOB YEARS
--------- ----- ------
Davis Sales 5
Gafney Clerk 5
Edwards Sales 7
Quill Mgr 10
指定 ORDER BY 作为整个 SELECT 语句中的最后一个子句。在此子句中命名的列可以是表达式或表的任何列。ORDER BY 子句中的列名不必在选择列表中指定。
可通过在 ORDER BY 子句中显式指定 ASC 或 DESC 将行按升序或降序进行排序。如果既未指定 ASC,也未指定 DESC,则自动按升序将行进行排序。下列语句按雇用年数以降序显示部门 84 中的雇员: SELECT NAME, JOB, YEARS
FROM STAFF
WHERE DEPT = 84
ORDER BY YEARS DESC
此语句产生下列结果: NAME JOB YEARS
--------- ----- ------
Quill Mgr 10
Edwards Sales 7
Davis Sales 5
Gafney Clerk 5
可以按字符值以及数字值将行进行排序。下列语句按姓名字母顺序显示部门 84 的雇员: SELECT NAME, JOB, YEARS
FROM STAFF
WHERE DEPT = 84
ORDER BY NAME
此语句产生下列结果:
NAME JOB YEARS
--------- ----- ------
Davis Sales 5
Edwards Sales 7
Gafney Clerk 5
Quill Mgr 10
当使用 SELECT 语句时,您可能不想要返回重复信息。例如,STAFF 有一个其中多次列出了几个部门编号的 DEPT 列,以及一个其中多次列出了几个工作说明的 JOB 列。
要消除重复行,在 SELECT 子句上使用 DISTINCT 选项。例如,如果将 DISTINCT 插入该语句,则部门中的每项工作仅列出一次: SELECT DISTINCT DEPT, JOB
FROM STAFF
WHERE DEPT < 30
ORDER BY DEPT, JOB
此语句产生下列结果: DEPT JOB
------ -----
10 Mgr
15 Clerk
15 Mgr
15 Sales
20 Clerk
20 Mgr
20 Sales
DISTINCT 已消除了在 SELECT 语句中指定的一组列中所有包含重复数据的行。
考虑运算次序是很重要的。一个子句的输出是下一个子句的输入,如下面列表中所示。给表达式命名中给出一个要考虑其中运算次序的示例。
并且注意,此说明允许以一种更直观的方式对查询进行考虑。此说明不一定是在内部执行运算的方式。运算顺序如下:
- FROM 子句
- WHERE 子句
- GROUP BY 子句
- HAVING 子句
- SELECT 子句
表达式是包括在语句中的计算或函数。下列语句计算,如果部门 38 中每个雇员都收到 $500 的奖金,则每人的薪水将是多少:
SELECT DEPT, NAME, SALARY + 500
FROM STAFF
WHERE DEPT = 38
ORDER BY 3
此结果为: DEPT NAME 3
------ --------- ----------------
38 Abrahams 12509.75
38 Naughton 13454.75
38 Quigley 17308.30
38 Marenghi 18006.75
38 O'Brien 18506.00
注意第三列的列名是一个数字。这是一个系统生成的数字,因为 SALARY+500 未指定列名。以后此数字在 ORDER BY 子句中用来表示第三列。给表达式命名论及如何给表达式取有意义的名称。
可使用基本算术运算符加(+)、减(-)、乘(*)、除(/)来形成算术表达式。
这些运算符可对几种不同类型操作数的值进行运算,其中某些操作数为:
- 列名(例如在 RATE*HOURS 中)
- 常数值(例如在 RATE*1.07 中)
- 标量函数(例如在 LENGTH(NAME) + 1 中)。
可选的 AS 子句允许您给表达式指定有意义的名称,这就使得以后再引用该表达式更容易。可使用 AS 子句为选择列表中的任何项提供名称。
下列语句显示其薪水加佣金少于 $13,000 的所有雇员。表达式 SALARY + COMM 命名为 PAY: SELECT NAME, JOB, SALARY + COMM AS PAY
FROM STAFF
WHERE (SALARY + COMM) < 13000
ORDER BY PAY
此语句产生下列结果: NAME JOB PAY
--------- ----- ----------
Yamaguchi Clerk 10581.50
Burke Clerk 11043.50
Scoutten Clerk 11592.80
Abrahams Clerk 12246.25
Kermisch Clerk 12368.60
Ngan Clerk 12714.80
通过使用 AS 子句,可以在 ORDER BY 子句中引用特定的列名而不是系统生成的数字。在此示例中,我们在 WHERE 子句中将(SALARY + COMM)与 13000 进行比较,而不是使用名称 PAY。这是运算次序的结果。在将(SALARY + COMM)命名为 PAY 之前计算 WHERE 子句的值。因此,不能在该谓词中使用 PAY。
可使用 SELECT 语句从两个或多个表中生成包含信息的报告。这通常称为 连接。例如,可以连接 STAFF 和 ORG 表中的数据以形成一个新表。要连接两个表,在 SELECT 子句中指定想要显示的列,在 FROM 子句中指定表名,在 WHERE 子句中指定搜索条件。WHERE 子句是可选的。
下一个示例使每个经理的姓名与部门名称关联。需要从两个表中选择信息,因为雇员信息(STAFF 表)和部门信息(ORG 表)是独立存储的。下列查询分别选择 STAFF 和 ORG 表的 NAME 和 DEPTNAME 列。搜索条件将选择范围缩小为 MANAGER 列中的值与 ID 列中的值相同的行: SELECT DEPTNAME, NAME
FROM ORG, STAFF
WHERE MANAGER = ID
图 3演示如何比较两个不同表中的列。加框线的值表示满足搜索条件的匹配项。
图 3. 从 STAFF 和 ORG 表中选择
SELECT 语句产生下列结果: DEPTNAME NAME
-------------- ---------
Mid Atlantic Sanders
South Atlantic Marenghi
New England Hanes
Great Lakes Plotz
Plains Fraye
Head Office Molinare
Pacific Lea
Mountain Quill
该结果列出每个经理的姓名和他或她的部门。
在编写 SELECT 语句时,可在 WHERE 子句中放置另一个 SELECT 语句。每个附加的 SELECT 启动一个子查询。
子查询本身又可包括其值代入其 WHERE 子句的另一个子查询。另外,WHERE 子句可将子查询包括在多个搜索条件中。子查询可引用与主查询中所使用的不同的表和列。
下列语句从 ORG 表中选择 STAFF 表中其 ID 为 280 的雇员的分部和位置: SELECT DIVISION, LOCATION
FROM ORG
WHERE DEPTNUMB = (SELECT DEPT
FROM STAFF
WHERE ID = 280)
在处理此语句时,DB2 首先确定子查询的结果。结果为 66,因为具有 ID 280 的雇员在部门 66。则最终结果从其部门号列具有值 66 的 ORG 表的行中得出。最终结果是: DIVISION LOCATION
---------- -------------
Western San Francisco
当使用子查询时,数据库管理程序计算该子查询并将结果值直接代入 WHERE 子句。
在相关子查询中进一步讨论子查询。
本节简要介绍了将用于全书示例的函数。 数据库函数是一组输入数据值和一个结果值之间的关系。
函数可以是内部的或用户定义的。 DB2 通用数据库提供很多内部函数和预安装的用户定义函数。可找到 SYSIBM 模式的内部函数和 SYSFUN 模式的预安装的用户定义函数。SYSIBM 和 SYSFUN 是保留模式。
内部函数和预安装的用户定义函数从不会满足所有需求。所以应用程序开发者可能需要创建自己的一套特定于他们的应用程序的函数。用户定义函数使这成为可能,例如通过扩展 DB2 通用数据库的范围以包括定制的商业或科学函数。这在用户定义函数中进一步讨论。
列函数对列中的一组值进行运算以得到单个结果值。下列就是一些列函数的示例。有关完整列表,参考 SQL Reference。
- AVG
- 返回某一组中的值除以该组中值的个数的和
- COUNT
- 返回一组行或值中行或值的个数
- MAX
- 返回一组值中的最大值
- MIN
- 返回一组值中的最小值
下列语句从 STAFF 表中选择最高薪水: SELECT MAX(SALARY)
FROM STAFF
此语句从员工 STAFF 样本表中返回值 22959.20。
下一个示例选择其收入超过平均收入但在公司的年数少于平均年数的雇员姓名和薪水。 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
在上面示例中的 WHERE 子句中,与直接实现列函数 (WHERE SALARY > AVG(SALARY)) 相反,在子查询中说明列函数。不能在 WHERE 子句中说明列函数。这是由于运算次序的结果。可认为 WHERE 子句是在 SELECT 子句之前进行计算的。因此,当正在计算 WHERE 子句时,列函数没有对该组值的存取权。稍后由 SELECT 子句选择这组值。
可指定 DISTINCT 作为列函数自变量的一部分,以在应用函数之前消除重复值。因此,COUNT(DISTINCT WORKDEPT) 计算不同部门的个数。
标量函数对值进行某个运算以返回另一个值。下列就是一些由DB2 通用数据库提供的标量函数的示例。
- ABS
- 返回数的绝对值
- HEX
- 返回值的十六进制表示
- LENGTH
- 返回自变量中的字节数(对于图形字符串则返回双字节字符数。)
- YEAR
- 抽取日期时间值的年份部分
有关标量函数的详细列表和说明,参考 SQL Reference。
下列语句返回 ORG 表中的部门名称以及其每个名称的长度: SELECT DEPTNAME, LENGTH(DEPTNAME)
FROM ORG
此语句产生下列结果: DEPTNAME 2
-------------- -----------
Head Office 11
New England 11
Mid Atlantic 12
South Atlantic 14
Great Lakes 11
Plains 6
Pacific 7
Mountain 8
注意:由于未使用 AS 子句给 LENGTH(DEPTNAME) 取一个有意义的名称,所以第二列中出现系统生成的数字。
DB2 通用数据库具有基于表的特定列对数据进行分析的能力。
可按照在 GROUP BY 子句中定义的组对行进行分组。以其最简单的形式,组由称为分组列的列组成。 SELECT 子句中的列名必须为分组列或列函数。列函数对于 GROUP BY 子句定义的每个组各返回一个结果。下列示例产生一个列出每个部门编号的最高薪水的结果: SELECT DEPT, MAX(SALARY) AS MAXIMUM
FROM STAFF
GROUP BY DEPT
此语句产生下列结果: DEPT MAXIMUM
------ ---------
10 22959.20
15 20659.80
20 18357.50
38 18006.00
42 18352.80
51 21150.00
66 21000.00
84 19818.00
注意:计算的是每个部门(由 GROUP BY 子句定义的组)而不是整个公司的 MAX(SALARY)。
分组查询可以在形成组和计算列函数之前具有消除非限定行的标准 WHERE 子句。必须在GROUP BY 子句之前指定 WHERE 子句。例如: 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
-------- ------- -----------
D11 17 18270.00
D21 15 27380.00
D21 16 36170.00
D21 17 28760.00
E11 12 15340.00
E21 14 26150.00
注意:在 SELECT 语句中指定的每个列名也在 GROUP BY 子句中提到。未在这两个地方提到的列名将产生错误。GROUP BY 子句对 WORKDEPT 和 EDLEVEL 的每个唯一组合各返回一行。
可应用限定条件进行分组,以便系统仅对满足条件的组返回结果。为此,在GROUP BY 子句后面包含一个 HAVING 子句。 HAVING 子句可包含一个或多个用 AND 和 OR 连接的谓词。每个谓词将组特性(如 AVG(SALARY))与下列之一进行比较:
例如,下列查询寻找雇员数超过 4 的部门的最高和最低薪水: 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 条件对整个表为真,则返回选择的结果(该结果必须整个由列函数组成);否则不返回任何行。 |