GBase 8s SQL 指南:教程———3编写SELECT语句

3编写SELECT语句

SELECT语句是最重要且最复杂的SQL语句。可使用它和SQL语句INSERT、 UPDATE和DELETE操纵数据。可以使用SELECT语句从数据库检索数据。将它用作 INSERT语句的一部分来生成新行或将它作为UPDATE语句的一部分来更新信息。

SELECT语句是查询数据库中信息的主要方法。它是检索程序、报告、表单或电子表格中 的数据的关键。可以将SELECT语句与查询工具DB-Access配合使用或在应用程序中嵌入 SELECT 语句。

本章介绍了使用SELECT语句查询和检索关系数据库数据的基本方法。本章讨论如何调整 语句以从一个或多个表中选择信息行和列,如何在SELECT语句中包含表达式和函数以 及如何创建数据库表之间的各种连接条件。SELECT语句的语法和使用方法在GBase 8s SQL指南:语法中有详细描述。

本出版物中的大部分示例来自stores_demo数据库中的各表,该数据库随GBase 8s SQL API 或数据库实用程序的软件提供。为了简便起见,示例只显示了每个SELECT语句检索的数 据的一部分。有关演示数据库的结构和内容的信息,请参阅《GBase 8s SQL参考指南》。 为了着重强调,虽然SQL不区分大小写,但是在示例中用大写字母显示关键字。

3.1介绍SELECT语句

SELECT语句允许您查看关系数据库中的数据的子句构成。这些子句允许您从一个或多个 表或视图中选择列和行、指定一个或多个条件、对数据进行排序和总结以及将选择的数据 放置在临时表中。

本章介绍了如何使用五个SELECT语句子句。如果包含全部五个子句,那么它们必须按照 下列顺序岀现在SELECT语句中:

Projection 子句
FROM子句
WHERE 子句
ORDER BY 子句
INTO TEMP 子句
只有Projection子句和FROM子句是必需的。这两个子句构成每个数据库查询的基础, 原因是它们指定要检索的列值,以及包含这些列的表。使用以下列表中的一个或多个其它 子句:

•添加WHERE子句以选择特定行或创建连接条件。

添加ORDER BY主键以更改生成数据的顺序。
添加INTO TEMP子句以将结果保存为表以供进一步查询。
还有两个SELECT语句子句GROUP BY和HAVING,使您可以执行更复杂的数据检索。 编写高级SELECT语句中对它们进行了描述。另一个子句INTO指定要从应用程序中的 SELECT语句中接收数据的程序或主变量。关于使用SELECT语句的完整语法和规则在 GBase 8s SQL指南:语法中有所描述。

SELECT语句的输出
虽然在所有GBase 8s产品中语法相同,但是结果输出的格式和显示取决于应用程序。本章 和编写高级SELECT语句中的示例如同您在DB-Access中使用“交互式查询语言”选项 时那样显示SELECT语句及输出。

大对象数据类型的输出

当发出包含大对象的SELECT语句时,DB-Access按如下所示显示结果:

对于TEXT列或CLOB列,显示列的内容。
对于BYTE列,显示词<BYTE value〉而不是实际值。
对于BLOB列,显示词<SBlob data>而不是实际值。
用户定义的数据类型的输出

DB-Access使用特殊约定来显示包含复杂或不透明数据类型的列的输出。

非缺省代码集的输出

可以发出查询NCHAR列而不是CHAR列,或者NVARCHAR列而不是VARCHAR列 的SELECT语句。

一些基本概念
SELECT语句不同于INSERT、UPDATE和DELETE语句,它不修改数据库中的数据。 一次只能有一个用户修改数据,而多个用户可同时查询或选择数据。有关修改数据的语句 的更多信息,请参阅修改数据。INSERT、UPDATE和DELETE语句的语法描述位于

《GBase 8s SQL指南:语法》中。

在关系数据库中,列是包含岀现在表中的每一行中的特定信息类型的数据元素。行是在数 据库表中的所有列上有关单个实体的信息的一组相关项。

可以从数据库表、系统目录表(包含有关数据库的信息的特殊表)、或视图(创建来包含 一组定制数据的虚拟表)中选择列和行。有关系统目录表的信息在GBase 8s SQL参考指 南中有所描述。

特权

在查询数据之前,确保您对数据库具有Connect特权和表的Select特权。通常这些特权授 予所有用户。在GBase 8s SQL指南:语法的GRANT和REVOKE语句中描述了数据库 访问权。

关系操作

关系操作涉及处理一个或多个表或者关系以产生另一个表,三种关系操作为选择、投影和 连接。本章包括选择、投影和连接操作的一些示例。

选择和投影

在关系术语中,选择被定义为取得满足特定条件的单个表的行的水平子集。此类SELECT 语句返回表中的某些行和所有列。选择是通过SELECT语句的WHERE子句实现的,如 下图所示:

图:查询

SELECT * FROM customer WHERE state = ‘NJ’;

该结果包含的列数与customer表相同,但只是后者的行的子集。在此示例中,DB-Access显 示单独行上来自每列的数据。

图:查询结果

customejnum 119

fname

Bob

lname

Shorter

company

The Triathletes Club

address1

2405 Kings Highway

address2

city

Cherry Hill

state

NJ

zipcode

08002

phone

609-663-6079

customejnum 122

fname

Cathy

lname

O’Brian

company

The Sporting Life

address1

543d Nassau

address2

city

Princeton

state

NJ

zipcode

08540

phone

609-342-0054

在关系术语中,投影被定义为从保留唯一行的单个表的列中获取垂直子集。此类S ELECT语 句返回表中的某些行和某些列。

投影是通过SELECT语句的Projection子句中的投影列表实现的。如下图所示。

图:查询

SELECT city, state, zipcode FROM customer;

此结果包含的列数与customer表相同,但只是投影表中列的子集。因为只从每行中选择一 小部分的数据,所以DB-Access能够在一行上显示行的所有数据。

图:查询结果

city state zipcode

Sunnyvale

CA

94086

San Francisco

CA

94117

Palo Alto

CA

94303

Redwood City

CA

94026

Los Altos

CA

94022

Mountain View

CA

94063

Palo Alto

CA

94304

Redwood City

CA

94063

Sunnyvale

CA

94086

Redwood City

CA

94062

Sunnyvale

CA

94085

Oakland

CA

94609

Cherry Hill

NJ

08002

Phoenix

AZ

85016

Wilmington

DE

19898

Princeton

NJ

08540

Jacksonville

FL

32256

Bartlesville

OK

74006

最常见的SELECT语句都同时使用选择和投影。此类查询返回表的某些行和某些列。如下 图所示。

图查询

SELECT UNIQUE city, state, zipcode

FROM customer

WHERE state = ‘NJ’;

图6包含customer表的列的子集和行的子集。

图:查询结果

city state zipcode

Cherry Hill NJ 08002

Princeton NJ 08540

连接

当两个或多个表被同一列或多个列连接时发生连接,它创建新的结果表。下图显示了一个 查询,该查询使用items和stock表的子集来说明连接的概念。

图:两个表之间的连接

SELECT UNOJE ltem_num. orO9r_num.
stock.stock_nMTi. desciip^iion

FROM items, slock

WHERE fiems.stock num = skx^k.stoclc num

正在上传…重新上传取消

正在上传…重新上传取消
下列查询将customer和state表连接起来。

图:查询

SELECT UNIQUE city, state, zipcode, sname

FROM customer, state

WHERE customer.state = state.code; 该结果包含customer和state表的指定行和列。

图:查询结果

city state zipcode sname

Bartlesville

OK

74006

Oklahoma

Blue Island

NY

60406

New York

Brighton

MA

02135

Massachusetts

Cherry Hill

NJ

08002

New Jersey

Denver

CO

80219

Colorado

Jacksonville

FL

32256

Florida

Los Altos

CA

94022

California

Menlo Park

CA

94025

California

Mountain View

CA

94040

California

Mountain View

CA

94063

California

Oakland

CA

94609

California

Palo Alto

CA

94303

California

Palo Alto

CA

94304

California

Phoenix

AZ

85008

Arizona

Phoenix

AZ

85016

Arizona

Princeton

NJ

08540

New Jersey

Redwood City

CA

94026

California

Redwood City

CA

94062

California

Redwood City

CA

94063

California

San Francisco

CA

94117

California

Sunnyvale

CA

94085

California

Sunnyvale

CA

94086

California

Wilmington

DE

19898

Delaware

3.2单个表的SELECT语句

可用多种方法查询数据库中的单个表。可用调整SELECT语句以执行以下操作:

,检索所有或指定的列

•检索所有或指定的行

,对检索到的数据执行计算或其它功能

,用各种方法对数据进行排序

最基本的SELECT语句只包含两个必需的子句,即Projection子句和FROM。

3.2.1使用星号(*)

下列查询在投影列表中指定manufact表中所有的列。显式投影列表是想要从表投影的列名 或表达式的列表。

图:查询

SELECT manu_code, manu_name, lead_time FROM manufact;

以下查询使用通配符星号()作为选择列表中的简写来表示表中所有名称相同的列。当想 要所有列按其定义的顺序排列时,可使用星号(),隐式选择列表使用星号。

图:查询

SELECT * FROM manufact;

因为manufact表只含有三列,图1和图2是等价的,并且显示相同的结果。即,manufact表 中每个列和行的列表。下图显示了结果。

图:查询结果

manu_code manu_name lead_time

SMT

Smith

3

ANZ

Anza

5

NRG

Norge

7

HSK

Husky

5

HRO

Hero

4

SHM

Shimara

30

KAR

Karsten

21

NKL

Nikolus

8

PRC

ProCycle

9

队列进行重新排序

下列查询显示了如何通过更改列在投影列表中的顺序。

图:查询

SELECT manu_name, manu_code, lead_time FROM manufact; 该查询结果包含与前一查询结果相同的列,但因为用不同的顺序指定了列,所以显示也不 同。

图:查询结果

manu_name manu_code lead_time

Smith

SMT

3

Anza

ANZ

5

Norge

NRG

7

Husky

HSK

5

Hero

HRO

4

Shimara

SHM

30

Karsten

KAR

21

Nikolus

NKL

8

ProCycle

PRC

9

3.2.2使用ORDER BY子句存储行

不以任何特定顺序排列查询的结果。例如:图4和图2以随机顺序显示。

可以将ORDER BY子句添加到您的SELECT语句里指导系统以特定顺序对数据进行排 序。ORDER BY子句是任何远程或本地表或视图中的列名的列表。投影列表中允许的所有 表达式在ORDER BY列表中也允许。如果在ORDER BY列表中使用的列具有选择触发 器,那么将不会激活该触发器。

以下查询返回manufact表中manu_code、manu_name和lead_time列的每一行。并根 据lead_time进行排序。

图:查询

SELECT manu_code, manu_name, lead_time

FROM manufact

ORDER BY lead_time;

对于GBase 8s,不需要在投影列表中包括您想要在ORDER BY子句中使用的列。即,可 以根据不在投影列表中检索的列对数据进行排序。以下查询返回manufact表

中 manu_code、manu_name列的每一行,并根据lead_time进行排序。lead_time列位于 ORDER BY子句中(尽管未包含在投影列表中)。

图:查询

SELECT manu_code, manu_name

FROM manufact

ORDER BY lead_time;

升序

缺省情况下,检索到的数据按升序顺序排序。在ASCII字符集中,升序是从大写字母A到 小写字母z,对于字符数据类型,那么是从最小值到最大值。DATE和DATETIME数据 按照从最早到最新排序,INTERVAL数据按从时间范围最短到最长排序。

降序

降序与升序相反,对于字符类型为从小写z到大写A,对于数字类型为从最大值到最小值。 DATE和DATETIME数据按照从最新到最早排序,INTERVAL数据按从时间范围最长到 最短排序。以下查询显示了降序的示例。

图:查询

SELECT * FROM manufact ORDER BY lead_time DESC;

列名后跟关键字DESC导致以降序对检索数据进行排序,如下图所示:

图:查询结果

manu_code manu_name lead_time

SHM

Shimara

30

KAR

Karsten

21

PRC

ProCycle

9

NKL

Nikolus

8

NRG

Norge

7

HSK

Husky

5

ANZ

Anza

5

HRO

Hero

4

SMT

Smith

3

您可以在ORDER BY子句中指定任何内置数据类型的列(TEXT、BYTE、BLOB或 CLOB除外),数据库服务器根据该列中的值对数据进行排序。

对多个列进行排序

还可以使用ORDER BY排序两个或多个列,这会创建嵌套排序。缺省值仍然是升序。在 ORDER BY子句中最先列出的列优先。

下列查询和图2及相应的查询结果显示了嵌套排序。要修改显示所选数据的顺序。更改在 ORDER BY子句中命名的两个列的顺序。

SELECT stock_num, manu_code, description, unit_price

FROM stock

ORDER BY manu_code, unit_price;

查询结果中,manu_code列数据按字母顺序显示,并且在同一 manu_code (例如:ANZ、 HRO)中,unit_price以升序列出。

图:查询结果

stock_num manu_code description unit_price

5 ANZ

tennis racquet

$19.80

9 ANZ

volleyball net

$20.00

6 ANZ

tennis ball

$48.00

313 ANZ

swim cap

$60.00

201 ANZ

golf shoes

$75.00

310 ANZ

kick board

$84.00

111 SHM

10-spd, assmbld

$499.99

112 SHM

12-spd, assmbld

$549.00

113 SHM

18-spd, assmbld

$685.90

5 SMT

tennis racquet

$25.00

6 SMT

tennis ball

$36.00

1 SMT

baseball gloves

$450.00

下列查询显示了 ORDER BY子句中列的相反顺序。

图查询

SELECT stock_num, manu_code, description, unit_price

FROM stock

ORDER BY unit_price, manu_code;

在此查询结果中,数据按unit_price的升序显示,其中两个或多个行具有相同的unit_price (例如:$20.00、$48.00、$312.00), manu_code 以字母顺序显示。

图: 查询结果

stock_num manu_code description unit_price

302 HRO

ice pack

$4.50

302 KAR

ice pack

$5.00

5 ANZ

tennis racquet

$19.80

9 ANZ

volleyball net

$20.00

103 PRC

frnt derailleur

$20.00

108 SHM

crankset

$45.00

6 ANZ

tennis ball

$48.00

305 HRO

first-aid kit

$48.00

303 PRC

socks

$48.00

311 SHM

water gloves

$48.00

113 SHM

18-spd, assmblc

1 $685.90

1 HSK

baseball gloves

$800.00

8 ANZ

volleyball

$840.00

4 HSK

football

$960.00

ORDER BY子句中的列的顺序十分重要,DESC关键字的位置也很重要。尽管下列查询中 的各语句在ORDER BY子句中包含相同的语句,但是每个语句产生的结果并不相同(没 有显示)。

图查询

SELECT * FROM stock ORDER BY manu_code, unit_price DESC;

SELECT * FROM stock ORDER BY unit_price, manu_code DESC;

SELECT * FROM stock ORDER BY manu_code DESC, unit_price;

SELECT * FROM stock ORDER BY unit_price DESC, manu_code;

3.2.3选择特定列

之前的章节显示了如何选择和排序表中所有的数据。然而,您经常希望看到的是一个或多 个特定列的数据。并且,公式是使用Projection和FROM子句指定列和表,并可以使用 ORDER BY子句按照升序或降序对数据进行排序。

如果想要操作orders表中的所有客户号,那么使用以下查询中的语句。

图:查询

SELECT customer_num FROM orders;

该结果显示了语句如何只选择orders表中customer_num列中的所有数据,并列出所有订单 上的客户号,包括重复的客户号。

图:查询结果

customer_num

104

101

104

122

123

124

126

127

输岀包括若干重复,原因是某些客户下了多个订单。有时您想要在投影中看到重复的行。 而有时您却只想看到特异值,而不是每个值都出的频率。

要抑制重复行,可在选择列表的开头包括关键字DISTINCT或其同义词UNIQUE,每个 查询级别一次,如以下查询所示。

图:查询

SELECT DISTINCT customer_num FROM orders;

SELECT UNIQUE customer_num FROM orders;

要生成更可读的表,图3将显示限制为仅显示一次orders表中的每个客户号。如下所示。

图:查询结果

customer_num

101

104

106

110

111

112

115

116

117

119

120

121

122

123

124

126

127

假设您正在处理客户电话,并且想要找到购买订单号DM354331。要列出orders表中的所 有购买订单号,使用诸如以下查询所示的语句。

图查询

SELECT po_num FROM orders;

该结果显示了如何检索到orders表中po_num列的数据。 图:查询结果

po_num

B77836

9270

B77890

8006

2865

Q13557

278693

然而,该列表顺序无用。可以添加ORDER BY子句来以升序对列数据进行排序,使得查 找特定po_num更容易,如下所示。

图查询

SELECT po_num FROM orders ORDER BY po_num;

图: 查询结果

po_num

278693

278701

2865

429Q

4745

8006

8052

9270

B77836

B77890

要从表中选择多个列,请在Projection子句的投影列表中列出它们。以下查询显示了选择 列的顺序就是检索列的顺序,从左到右。

图查询

SELECT ship_date, order_date, customer_num,

order_num, po_num

FROM orders

ORDER BY order_date, ship_date;

如对多个列进行排序所示,可以使用ORDER BY子句来以升序或降序对数据进行排序和 执行嵌套排序。此结果显示了升序。

图:查询结果

ship_date ordejdate customejnum

order_num po_num

06/01/1998 05/20/1998

104

1001 B77836

05/26/1998 05/21/1998

101

1002 9270

05/23/1998 05/22/1998

104

1003 B77890

05/30/1998 05/22/1998

106

1004 8006

06/09/1998 05/24/1998

116

1005 2865

05/30/1998 112

1006 Q13557

06/05/1998 05/31/1998

117

1007 278693

07/06/1998 06/07/1998

110

1008 LZ230

06/21/1998 06/14/1998

111

1009 4745

06/29/1998 06/17/1998

115

1010 429Q

06/29/1998 06/18/1998

117

1012 278701

07/03/1998 06/18/1998

104

1011 B77897

07/10/1998 06/22/1998

104

1013 B77930

07/03/1998 06/25/1998

106

1014 8052

07/16/1998 06/27/1998

110

1015 MA003

07/12/1998 06/29/1998

119

1016 PC6782

07/13/1998 07/09/1998

120

1017 DM354331

07/13/1998 07/10/1998

121

1018 S22942

07/16/1998 07/11/1998

122

1019 Z55709

07/16/1998 07/11/1998

123

1020 W2286

07/25/1998 07/23/1998

124

1021 C3288

07/30/1998 07/24/1998

126

1022 W9925

07/30/1998 07/24/1998

127

1023 KF2961

当对表中的若干列使用SELECT和ORDER BY时,您会发现使用整数来在ORDER BY 子句中表示列的位置非常有用。当整数是ORDER BY列表中的元素时。数据库服务器将 它看作是投影列表中的位置。例如,在ORDER BY列表中使用3 (ORDER BY 3)表示 投影列表中的第三项。以下查询中的语句检索和显示相同数据,如下图12所示。

图:查询

SELECT customer_num, order_num, po_num, order_date

FROM orders

ORDER BY 4, 1;

SELECT customer_num, order_num, po_num, order_date

FROM orders

ORDER BY order_date, customer_num;

图:查询结果

customer_num

order_num po_num

order_date

104

1001 B77836

05/20/1998

101

1002 9270

05/21/1998

104

1003 B77890

05/22/1998

106

1004 8006

05/22/1998

116

1005 2865

05/24/1998

112

1006 Q13557

05/30/1998

117

1007 278693

05/31/1998

110

1008 LZ230

06/07/1998

111

1009 4745

06/14/1998

115

1010 429Q

06/17/1998

104

1011 B77897

06/18/1998

117

1012 278701

06/18/1998

104

1013 B77930

06/22/1998

106

1014 8052

06/25/1998

110

1015 MA003

06/27/1998

119

1016 PC6782

06/29/1998

120

1017 DM354331

07/09/1998

121

1018 S22942

07/10/1998

122

1019 Z55709

07/11/1998

123

1020 W2286

07/11/1998

124

1021 C3288

07/23/1998

126

1022 W9925

07/24/1998

127

1023 KF2961

07/24/1998

当将整数指定给列名时,可以在ORDER BY子句中包括DESC关键字。如下所示。

图查询

SELECT customer_num, order_num, po_num, order_date

FROM orders

ORDER BY 4 DESC, 1;

在此示例中,数据先按order_date以降序排序再按customer_num以升序排序。

选择子串

要选择字符列的部分值,请在投影列表中包含一个子串。假设市场营销部门计划向客户寄 邮件并想要客户的基于邮政编码的地理分布。可编写与以下图中显示的查询相似的查询。

图查询

SELECT zipcode[1,3], customer_num

FROM customer

ORDER BY zipcode;

该查询使用子串来选择zipcode列的前三个字符(它们标识州)和全部customer_num,并 按邮政编码以升序列出它们,如以下结果所示。

图:查询结果

zipcode customer_num

021

125

080

119

085

122

198

121

322

123

943

103

943

107

946

118

ORDER BY和非英文数据

缺省情况下,对于数据库数据,GBase 8s数据库服务器使用美国英语语言环境,称为语言 环境。美国英语语言环境指定数据以代码集顺序存储。此缺省语言环境使用ISO 8859-1代 码集。

如果您的数据库包含非英语数据,那么应在NCHAR (或NVARCHAR)列中存储非英语 数据,以获取按语言排序的结果。ORDER BY子句应以适合于语言的顺序返回数据。

3.2.4使用 WHERE子句

SELECT语句返回的行集是其活动集。单个SELECT语句返回单个行。如果只想看见特 定行,可将WHERE子句添加至SELECT语句。例如:使用WHERE子句来将数据库服 务器返回的行限制为特定客户所下的订单或特定客户服务代表输入的电话。

可以使用WHERE子句来设置比较条件或连接条件。本节只演示第一种用法。连接条件在 后面的节和下一章中描述。

3.2.5创建比较条件

SELECT语句的WHERE子句指定了您想要看到的行。比较条件使用特定关键字和运算符 来定义搜索条件。

例如,可使用BETWEEN、IN、LIKE或 MATCHES中的一个来测试相等性。或者使 用关键字IS NULL来测试空值。可将关键字NOT与这些关键字中的任何一个组合来指 定相反条件。

下表列出可在WHERE子句中用来代替关键字测试相等性的关系运算符。

运算符

操作

等于

!=或 <>

不等于

大于

=

大于并或等于

<

小于

<=

小于或等于

对于CHAR表达式,大于在ASCII整理顺序中意味着之后,其中小写字母在大写字母之 后,而大写字母和小写字母都在数字之后。请参阅《GBase 8s SQL指南:语法》中的ASCII 字符集图表。对于DATE和DATETIME表达式,大于意味着时间上更迟,对于 INTERVAL表达式,它意味着更长的持续时间。

不能使用TEXT或BYTE列创建比较条件(使用IS NULL或IS NOT NULL关键字来 测试NULL值时除外)。

不能指定BLOB或CLOB列从而在GBase 8s上创建比较条件(用IS NULL或IS NOT NULL关键字来测试NULL值时除外)。

可以在WHERE子句中使用上述关键字或运算符来创建执行下列操作的比较条件查询:

包括值
•排除值

查找值范围
•查找值的子集

标识NULL值
要使用以下条件执行变量文本搜索,在WHERE子句中使用上述关键字或运算符来创建比 较条件查询:

•精确文本比较

•单字符通配符

•受限单字符通配符

可变长通配符
下标
下一节包含说明这些查询类型的示例。

包括行

在WHERE子句中使用等号(=)关系运算符包括行,如以下查询所示。

图:查询

SELECT customer_num, call_code, call_dtime, res_dtime

FROM cust_calls

WHERE user_id = ‘maryj’;

该查询返回以下行集。

图:查询结果

customer_num call_code call_dtime res_dtime

106 D 1998-06-12 08:20 1998-06-12 08:25

121 O 1998-07-10 14:05 1998-07-10 14:06

127 I 1998-07-31 14:30

排除行

在WHERE子句中使用关系运算符!=或 <> 排除行。

以下查询假设您从符合ANSI的数据库中选择;该语句指定所有者或customer表的创建者 的登录名。当表的创建者就是当前用户时,或者当数据库不符合ANSI时,不需要此限定 符。然而,在任一情况下都可以包括该限定符。有关所有者命名的详细讨论,请参阅《GBase 8s SQL指南:语法》。

图:查询

SELECT customer_num, company, city, state

FROM odin.customer

WHERE state != ‘CA’;

SELECT customer_num, company, city, state

FROM odin.customer

WHERE state <> ‘CA’;

此查询中的两个语句都通过指定在用户odin拥有的customer表中state列中的值不应等 于CA来排除值,如下所示。

图:查询结果

customer_num

company

city

state

119

The Triathletes Club Cherry Hill

NJ

120

Century Pro Shop

Phoenix

AZ

121

City Sports

Wilmington

DE

122

The Sporting Life

Princeton

NJ

123

Bay Sports

Jacksonville

FL

124

Putnum’s Putters

Bartlesville

OK

125

Total Fitness Sports Brighton

MA

Neelie’s Discount Sp Denver CO
Big Blue Bike Shop Blue Island NY
Phoenix College Phoenix AZ
指定一定范围的行

下列查询显示在WHERE子句中指定一定范围内行的两种方法。

图查询

SELECT catalog_num, stock_num, manu_code, cat_advert

FROM catalog

WHERE catalog_num BETWEEN 10005 AND 10008;

SELECT catalog_num, stock_num, manu_code, cat_advert

FROM catalog

WHERE catalog_num >= 10005 AND catalog_num <= 10008;

查询中的每个子句都指定catalog_num的范围,从10005至10008 (包括10005和 10008),第一个语句使用关键字,第二个语句使用关系运算符检索行。如下所示。

图:查询结果

catalog_num 10005

stock_num

3

manu_code

HSK

cat_advert

High-Technology Design Expands the Sweet Spot

catalog_num

10006

stock_num

3

manu_code

SHM

cat_advert

Durable Aluminum for High School and Collegiate Athletes

catalog_num

10007

stock_num

4

manu_code

HSK

cat_advert

Quality Pigskin with Joe Namath Signature

catalog_num

10008

stock_num

4

manu_code

HRO

cat_advert Highest Quality Football for High School and Collegiate Competitions

尽管catalog表标记具有BYTE数据类型的列,但该列不包括在此SELECT语句中,原因 是输出将按列名只显示词<BYTE value>。可以编写SQL API应用程序来显示TEXT和 BYTE 值。

排除一定范围的行

以下查询使用关键字NOT BETWEEN排除zipcode列中字符范围在94000到94999的 行,如下所示。

图:查询

SELECT fname, lname, city, state

FROM customer

WHERE zipcode NOT BETWEEN ‘94000’ AND ‘94999’

ORDER BY state;

图:查询结果

fname

lname

city

state

Frank

Lessor

Phoenix

AZ

Fred

Jewell

Phoenix

AZ

Eileen

Neelie

Denver

CO

Jason

Wallack

Wilmington

DE

Marvin

Hanlon

Jacksonville

FL

James

Henry

Brighton

MA

Bob

Shorter

Cherry Hill

NJ

Cathy

O’Brian

Princeton

NJ

Kim

Satifer

Blue Island

NY

Chris

Putnum

Bartlesville

OK

使用WHERE子句査找值的子集

就像排除行,以下查询假定使用符合ANSI的数据库。所有者限定符在引号中,以保护文 字字符串的区分大小写。

图:查询

SELECT lname, city, state, phone

FROM ‘Aleta’.customer

WHERE state = ‘AZ’ OR state = ‘NJ’

ORDER BY Iname;

SELECT lname, city, state, phone

FROM ‘Aleta’.customer

WHERE state IN (‘AZ’, ‘NJ’) ORDER BY lname;

查询中的每个语句在Aleta. customer表的state列中检索包括AZ或NJ子集的行。

图:查询结果

lname

city

state phone

Jewell

Phoenix

AZ

602-265-8754

Lessor

Phoenix

AZ

602-533-1817

O’Brian

Princeton

NJ

609-342-0054

Shorter

Cherry Hill

NJ

609-663-6079

不能使用IN关键字来测试TEXT或BYTE列。

另外,当使用GBase 8s时,不能使用IN关键字来测试BLOB或CLOB列。

在查询(对符合ANSI的数据库进行查询的示例)中,表所有者名称两边没有引号。鉴于 图1中两个语句搜索Aleta.customer表,以下查询搜索表ALETA.customer,这是一个不同 的表,原因在于符合ANSI的数据库查看所有者名称的方式。

图查询

SELECT lname, city, state, phone

FROM Aleta.customer

WHERE state NOT IN (‘AZ’, ‘NJ’)

ORDER BY state;

上一个查询添加了关键字NOT IN,以便子集更改为排除state列中的子集AZ和NJ,下图 以state列的顺序显示结果。

图: 查询结果

lname

city

state phone

Pauli

Sunnyvale

CA

408-789-8075

Sadler

San Francisco

CA

415-822-1289

Currie

Palo Alto

CA

415-328-4543

Higgins

Redwood City

CA

415-368-1100

Vector

Los Altos

CA

415-776-3249

Watson

Mountain View

CA

415-389-8789

Ream

Palo Alto

CA

415-356-9876

Quinn

Redwood City

CA

415-544-8729

Miller

Sunnyvale

CA

408-723-8789

Jaeger

Redwood City

CA

415-743-3611

Keyes

Sunnyvale

CA

408-277-7245

Lawson

Los Altos

CA

415-887-7235

Beatty

Menlo Park

CA

415-356-9982

Albertson

Redwood City

CA

415-886-6677

Grant

Menlo Park

CA

415-356-1123

Parmelee

Mountain View

CA

415-534-8822

Sipes

Redwood City

CA

415-245-4578

Baxter

Oakland

CA

415-655-0011

Neelie

Denver

CO

303-936-7731

Wallack

Wilmington

DE

302-366-7511

Hanlon

Jacksonville

FL

904-823-4239

Henry

Brighton

MA

617-232-4159

Satifer

Blue Island NY

312-944-5691

Putnum

Bartlesville

OK

918-355-2074

标识NULL值

使用IS NULL或IS NOT NULL选项检查NULL值。NULL值表示没有数据或未知值。

NULL值不等同于零或空白。

以下查询返回具有空paid_date的所有行,如下所示。

图:查询

SELECT order_num, customer_num, po_num, ship_date

FROM orders

WHERE paid_date IS NULL

ORDER BY customer_num;

图:查询结果

ordejnum customejnum po_num ship_date

1004

106

8006

05/30/1998

1006

112

Q13557

1007

117

278693

06/05/1998

1012

117

278701 06/29/1998

1016

119

PC6782 07/12/1998

1017

120

DM354331 07/13/1998

构成复合条件

要连接两个或多个比较条件或Boolean表达式,使用逻辑运算符AND、OR和NOT。

Boolean表达式的值求出为true或false,如果涉及到NULL值,那么为unknown。

在以下查询中,运算符AND组合WHERE子句中的两个比较表达式。

图:查询

SELECT order_num, customer_num, po_num, ship_date

FROM orders

WHERE paid_date IS NULL

AND ship_date IS NOT NULL

ORDER BY customer_num;

该查询返回具有NULL paid_date或NOT NULL ship_date的所有值。

图:查询结果

order_num customer_num po_num ship_date

1004

106 8006

05/30/1998

1007

117 278693

06/05/1998

1012

117 278701

06/29/1998

1017

120 DM354331

07/13/1998

使用精确文本比较

以下示例包含一个WHERE子句,它通过使用关键字LIKE或MATCHES或者等号(=) 关系运算符来搜索精确文本比较。与较早的示例不同,这些示例说明如何查询不在当前数 据库中的表。仅当包含该表的数据库与当前数据库的ANSI兼容状态相同时,才能访问不 在当前数据库中的表。如果当前数据库是符合ANSI的数据库,那么要访问的表必须也驻 留在符合ANSI的数据库中。如果当前数据库不是符合ANSI的数据库,那么要访问的 表必须也驻留在不符合ANSI的数据库中。

虽然本章前面使用的数据库是演示数据库,但是下列示例中的FROM子句指定了由所有 者bubba创建的manatee表,该表驻留在名为syzygy的符合ANSI的数据库中。有关如何 访问不在不在当前数据库中的表的更多信息,请参阅《GBase 8s SQL指南:语法》。

下列查询中的每个语句检索description列中具有单词helmet的所有行,如下所示。

图查询

SELECT stock_no, mfg_code, description, unit_price

FROM syzygy:bubba.manatee

WHERE description = ‘helmet’

ORDER BY mfg_code;

SELECT stock_no, mfg_code, description, unit_price

FROM syzygy:bubba.manatee

WHERE description LIKE ‘helmet’

ORDER BY mfg_code;

SELECT stock_no, mfg_code, description, unit_price

FROM syzygy:bubba.manatee

WHERE description MATCHES ‘helmet’ ORDER BY mfg_code;

该结果可能如下图所示。

图:查询结果

stock_no mfg_code description unit_price

991 ABC helmet

991 BKE helmet

991 HSK helmet

991 PRC helmet

991 SPR helmet

$222.00

$269.00

$311.00

$234.00

$245.00

使用变量文本搜索

可对基于字段的子串搜索的变量文本查询使用关键字LIKE和MATCHESo包含关键字 NOT以指示相反的条件。

关键字LIKE是SQL的ISO/ANSI标准,而 MATCHES是GBase 8s扩展。

变量文本搜索字符串可将列出的通配符与下表中的LIKE或MATCHES包括在一起。 下表显示了您可以与关键字LIKE和MATCHES 一起使用的通配符。说明了这些符号及 其含义。

关键字符号 含义

关键字

符号

含义

LIKE

%

求值为零或多个字符

LIKE

求值为单个字符

LIKE

\

对下一字符的特殊有效位数进行转义

MATCHES

求值为零个或多个字符

MATCHES

?

求值为单个字符(空值除外)

MATCHES

::

求值为单个字符或一定范围内的值

MATCHES

\

对下一字符的特殊有效位数进行转义

不能使用LIKE或 MATCHES运算符测试BLOB、CLOB、TEXT或BYTE列。

使用单字符通配符

下列查询中的语句说明如何在WHERE子句中使用单字符通配符。而且,它们还演示了如 何查询非当前数据库中的表。stock表位于数据库sloth中。除了在当前演示数据库外部之外, sloth还在称为meerkat的独立数据库服务器上。

有关更多信息,请参阅在外部数据库中访问和修改数据和《GBase 8s SQL指南:语法》。

图查询

SELECT stock_num, manu_code, description, unit_price

FROM sloth@meerkat:stock

WHERE manu_code LIKE ‘R

AND unit_price >= 100

ORDER BY description, unit_price;

SELECT stock_num, manu_code, description, unit_price

FROM sloth@meerkat:stock

WHERE manu_code MATCHES ‘?R?’

AND unit_price >= 100 ORDER BY description, unit_price;

查询中的每个语句只检索manu_code的中间字母是R的那些行。如下所示。比较’R’(对 于LIKE)或’?R?’(对于MATCHES)从左到右指定下列项:

•任何单个字符

• 字母R

•任何单个字符

图:查询结果

stock_num manu_code description unit_price

205 HRO

3 golf balls

$312.00

2 HRO

baseball

$126.00

1 HRO

baseball gloves

$250.00

7 HRO

basketball

$600.00

102 PRC

bicycle brakes

$480.00

114 PRC

bicycle gloves

$120.00

4 HRO

football

$480.00

110 PRC

helmet

$236.00

110 HRO

helmet

$260.00

307 PRC

infant jogger

$250.00

306 PRC

tandem adapter

$160.00

308 PRC

twin jogger

$280.00

304 HRO

watch

$280.00

指定一定范围内的词首字符的WHERE子句

下列查询只选择manu_code以A到H开头的那些列,并返回结果显示的行。测试’[A-H]’ 指定从A到H之间(包括A和H)的任何一个字母。对于LIKE关键字,不存在等价的 通配符。

图:查询

SELECT stock_num, manu_code, description, unit_price

FROM stock

WHERE manu_code MATCHES ‘[A-H]*’

ORDER BY description, manu_code;

图:查询结果

stock_num manu_code description unit_price

205 ANZ

3 golf balls

$312.00

205 HRO

3 golf balls

$312.00

2 HRO

baseball

$126.00

3 HSK

baseball bat

$240.00

1 HRO

baseball gloves

$250.00

1 HSK

baseball gloves

$800.00

7 HRO

basketball

$600.00

313 ANZ

swim cap

$60.00

6 ANZ

tennis ball

$48.00

5 ANZ

tennis racquet

$19.80

8 ANZ

volleyball

$840.00

9 ANZ

volleyball net

$20.00

304 ANZ

watch

$170.00

具有可变长通配符的WHERE子句

下列查询中的语句在字符串的末尾使用通配符来检索description以字符bicycle开头的所 有行。

图查询

SELECT stock_num, manu_code, description, unit_price

FROM stock

WHERE description LIKE ‘bicycle%’

ORDER BY description, manu_code;

SELECT stock_num, manu_code, description, unit_price

FROM stock

WHERE description MATCHES ‘bicycle*’

ORDER BY description, manu_code;

任一语句都返回以下行。

图:查询结果

stock_num manu_code description unit_price

102 PRC

bicycle brakes

$480.00

102 SHM

bicycle brakes

$220.00

114 PRC

bicycle gloves

$120.00

107 PRC

bicycle saddle

$70.00

106 PRC

bicycle stem

$23.00

101 PRC

bicycle tires

$88.00

101 SHM

bicycle tires

$68.00

105 PRC

bicycle wheels

$53.00

105 SHM

bicycle wheels

$80.00

SBASe*

比较’bicycle%'或’bicycle*'指定字符bicycle后跟零个字符或任何字符序列。它与bicycle stem匹配,而stem与通配符匹配。如果具有该描述的行存在,那么它只与字符bicycle匹 配。

以下查询通过添加排除PRC的manu_code的另一个比较条件来缩小搜索范围。

图:查询

SELECT stock_num, manu_code, description, unit_price

FROM stock

WHERE description LIKE ‘bicycle%’

AND manu_code NOT LIKE ‘PRC’

ORDER BY description, manu_code;

该语句只检索到下列行。

图:查询结果

stock_num manu_code description unit_price

102 SHM bicycle brakes $220.00

101 SHM bicycle tires $68.00

105 SHM bicycle wheels $80.00

当从大型表中进行选择并在比较字符串中使用词首通配符时(如’%cycle’),查询通常需 要较长时间来执行。由于不能使用索引,所以搜索每一行。

MATCHES子句和非缺省语言环境

缺省情况下,对数据库数据,GBase 8s数据库服务器使用美国英语语言环境,称为语言环 境。缺省的语言环境使用ISO 8859-1代码集。该美国英语语言环境指定MATCHES将使 用代码集顺序。

如果数据库使用非缺省语言环境,那么指定范围的MATCHES子句将该语言环境的整理顺 序用于字符数据类型(包括CHAR、NCHAR、VARCHAR、NVARCHAR和 LVARCHAR)。MATCHES范围的此功能是一般规则(只有NCHAR和NVARCHAR列 可使用特定于语言环境的整理)的例外情况。然而,如果语言环境不能指定任何特殊整理 顺序,那么MATCHES使用代码集顺序。

在GBase 8s中,可以使用SET COLLATION语句为会话指定不同于DB_LOCALE设置的 数据库语言环境。有关SET COLLATION的描述,请参阅《GBase 8s SQL指南:语法》。 保护特殊字符

下列查询使用ESCAPE与LIKE或MATCHES配合使用,以便您可以保护特殊字符,使 它们不会被误认为是通配符。

图查询

SELECT * FROM cust_calls

WHERE res_descr LIKE ‘%!%%’ ESCAPE

ESCAPE关键字指定包含下一个字符的转义字符(在本示例中为!)以便将它解释为数据 而不是通配符。在该示例中,转义字符导致将中间的百分号(%)当作数据。通过使用 ESCAPE关键字,您可以使用LIKE通配符百分号(%)在res_descr列中搜索百分号(%) 的岀现次数。查询检索下列显示的行。

图:查询结果

customejnum 116

call_dtime 1997-12-21 11:24

user_id mannyn

call_code I

call_descr Second complaint from this customer!

Received two cases righthanded outfielder

glove (1 HRO) instead of one case lefties.

res_dtime 1997-12-27 08:19

res_descr Memo to shipping (Ava Brown) to send case

of lefthanded gloves, pick up wrong case;

memo to billing requesting 5% discount to placate customer due to second offense and lateness of resolution because of holiday.

在WHERE子句中使用下标

您可以在SELECT语句的WHERE子句中使用下标,以指定选择某列中一定范围内额字 符或数字,如下所示。

SELECT catalog_num, stock_num, manu_code, cat_advert,

cat_descr

FROM catalog

WHERE cat_advert[1,4] = ‘High’;

下标[1,4]导致该查询检索cat_advert列的前四个字母为High的所有行。如下所示。

图: 查询结果

catalog_num 10004

stock_num 2

manu_code HRO

SBASe*

cat_advert Highest Quality Ball Available, from Hand-Sti tching to the Robinson Signature

cat_descr

Jackie Robinson signature ball. Highest professional quality, used by National League.

catalog_num 10005

stock_num 3

manu_code HSK

cat_advert High-Technology Design Expands the Sweet Spot cat_descr

Pro-style wood. Available in sizes: 31,32, 33, 34, 35.

catalog_num 10045

stock_num 204

manu_code KAR

cat_advert High-Quality Beginning Set of Irons. Appropriate for High School Competitions

cat_descr

Ideally balanced for optimum control. Nylon covered shaft.

catalog_num 10068

stock_num 310

manu_code ANZ

cat_advert High-Quality Kickboard

cat_descr

White. Standard size.

3.2.6使用FIRST子句选择特定行

可以在SELECT语句的Projection子句中包含FIRST max规范(其中max具有整数值) 来构建查询,使其仅返回匹配SELECT语句条件的最初max行。在(且仅在)此上下文中, 也可以使用关键字LIMIT作为FIRST的同义词。执行具有FIRST子句的SELECT语句 时返回的行可能会不同,这取决于该语句是否还包含ORDER BY子句。

在Projection子句中,后面跟无符号整数的关键字SKIP可用在FIRST或LIMIT关键字 前面。SKIP offset子句指示数据库服务器在返回FIRST子句指定的行数之前,从查询结果 集中排除最初offset行满足条件的行。在SPL例程中,SKIP、FIRST或LIMIT的参数

可以是字面值整数或局部SPL变量。如果Projection子句包含SKIP offset但不包含

FIRST或LIMIT规范,那么查询返回除最初offset行以外所有满足条件的行。

Projection子句在下列上下文中不能包含SKIP、FIRST或LIMIT关键字:

•当SELECT语句是视图定义的一部分

• 在子查询中,除了外部查询的FROM子句

•在跨服务器分发的查询中,其中参与的数据库服务器不支持SKIP、FIRST或

LIMIT关键字。

有关使用FIRST子句的限制的信息,请参阅《GBase 8s SQL指南:语法》中SELECT语 句的Projection子句的描述。

不具有ORDER BY子句的FIRST子句

如果具有FIRST子句的SELECT语句中没有ORDER BY子句,那么可能返回符合

SELECT语句条件的任何行。换言之,数据库服务器确定返回哪些限定行,并且查询结果 可能会不同,这取决于优化器选择的查询计划。

以下查询使用FIRST子句来返回state表中的前五行。

图:查询

SELECT FIRST 5 * FROM state;

图:查询结果

code sname

AK Alaska

HI Hawaii

CA California

OR Oregon

WA Washington

当只想知道表包含的所有列的名称和数据的类型,或者测试可能会返回许多行的查询时, 可以使用FIRST子句。以下查询显示了如何使用FIRST子句来返回表的第一行的列值。

图:查询

SELECT FIRST 1 * FROM orders;

图:查询结果

order_num 1001

order_date 05/20/1998

customer_num 104

ship_instruct express

backlog

n

po_num

B77836

ship_date

06/01/1998

ship_weight

20.40

ship_charge

$10.00

paid_date

07/22/1998

具有ORDER BY子句的FIRST子句

可以在具有FIRST子句的SELECT语句中包括ORDER BY子句,以返回包含指定列的 最高值或最低值的行。以下查询显示了包含ORDER BY子句以(按字母顺序)返回包含 在state表中的前五个州的查询。该查询,(除ORDER BY子句以外,它与图1相同)返 回不同于图1的一组行。

图:查询

SELECT FIRST 5 * FROM state ORDER BY sname;

图:查询结果

code sname

AL Alabama

AK Alaska

AZ Arizona

AR Arkansas

CA California

以下查询显示如何在具有ORDER BY子句的查询中使用FIRST子句来查找stock表中 列出的10中最贵的商品。

图:查询

SELECT FIRST 10 description, unit_price

FROM stock ORDER BY unit_price DESC;

图:查询结果

description unit_price

football

$960.00

volleyball

$840.00

baseball gloves

$800.00

18-spd, assmbld

$685.90

irons/wedge

$670.00

basketball $600.00

12-spd, assmbld $549.00

10-spd, assmbld $499.99

football $480.00

bicycle brakes $480.00

应用程序可以将Projection子句的SKIP和FIRST关键字与ORDER BY子句相结合使 用,以执行连续查询,对某些固定大小(例如,最大行数可在一屏显示,无需滚动)的子 集中所有满足条件的行进行增量检索。通过在每次查询后使用FIRST子句的max参数增 大SKIP子句的offset参数值可实现上述操作。通过对满足条件的行施加唯一的命令, ORDER BY子句确保每次查询返回满足条件行的不同子集。

以下查询显示了包含SKIP、FIRST和ORDER BY规范以(按字母顺序)返回state表的 10个州中的第六个州,而不是前五个州的查询。该查询类似于图1,但SKIP 5规范指示 数据库服务器返回不同于图1的行集。

图:查询

SELECT SKIP 5 FIRST 5 * FROM state ORDER BY sname;

图:查询结果

code sname

CO Colorado

CT Connecticut

DE Delaware

FL Florida

GA Georgia

如果使用SKIP、FIRST和ORDER BY关键字,必须指定对应于应用程序设计目标的参 数,如果SKIP的offset参数大于满足条件的行数,那么任何FIRST或LIMIT规范都无 效,并且查询不会返回任何结果。

3.2.7表达式和派生的值

不限制您按名称选择列。可以在SELECT语句的Projection子句中列出表达式来执行对列 数据的计算,并显示派生自一列或多列的内容的信息。

表达式由列名、常量、带引号字符串、关键字或用运算符连接的这些项的任何组合组成。 当在程序中嵌入SELECT语句时,它还可以包括主变量(程序数据)。

算术表达式

算术运算符至少包含下表中列出的算术运算符之一并产生一个数字

运算符

操作

/

不能在算术表达式中使用TEXT或BYTE列。

在GBase 8s,不能在算术表达式中指定BLOB或CLOB。

算术表达式使您能够查看建议的计算的结果而不必实际改变数据库中的数据。可以添加 INTO TEMP子句来将已改变的数据保存在临时表中以供将来参考、计算或即时报告。

当unit_price为$400或更多时,以下查询对unit_price列计算7%的销售税(但不在数据 库中更新它)。

图:查询

SELECT stock_num, description, unit_price, unit_price * 1.07

FROM stock

WHERE unit_price >= 400;

此结果在expression列中显示。

图:查询结果

stock_num description unit_price (expression)

1 baseball gloves

$800.00

$856.00

1 baseball gloves

$450.00

$481.50

4 football

$960.00

$1027.20

4 football

$480.00

$513.60

7 basketball

$600.00

$642.00

8 volleyball

$840.00

$898.80

102 bicycle brakes

$480.00

$513.60

111 10-spd, assmbld

$499.99

$534.99

112 12-spd, assmbld

$549.00

$587.43

113 18-spd, assmbld

$685.90

$733.91

203 irons/wedge $670.00 $716.90

当订货数量小于5时,下列查询对订单计算$6.50的附加费用。

图查询

SELECT item_num, ordejnum, quantity,

total_price, total_price + 6.50

FROM items

WHERE quantity < 5;

结果显示在expression列中。

图:查询结果

item_num order_num quantity total_price (expression)

1

1001

1

$250.00

$256.50

1

1002

1

$960.00

$966.50

2

1002

1

$240.00

$246.50

1

1003

1

$20.00

$26.50

2

1003

1

$840.00

$846.50

1

1004

1

$250.00

$256.50

2

1004

1

$126.00

$132.50

3

1004

1

$240.00

$246.50

4

1004

1

$800.00

$806.50

1

1023

2

$40.00

$46.50

2

1023

2

$116.00

$122.50

3

1023

1

$80.00

$86.50

4

1023

1

$228.00

$234.50

5

1023

1

$170.00

$176.50

6

1023

1

$190.00

$196.50

下列查询计算并在expression列中显示按接收到客户电话(call_dtime)与处理电话 (res_dtime)之间的时间间隔(以天、小时和分钟计)。

图查询

SELECT customejnum, call_code, call_dtime,

res_dtime - call_dtime

FROM cust_calls

ORDER BY customer_num;

图: 查询结果

customer_num call_code call_dtime (expression)

106 D

1998-06-12 08:20

0 00:05

110 L

1998-07-07 10:24

0 00:06

116 I

1997-11-28 13:34

0 03:13

116 I

1997-12-21 11:24

5 20:55

119 B

1998-07-01 15:00

0 17:21

121 O

1998-07-10 14:05

0 00:01

127 1

1998-07-31 14:30

使用显示标签

可以将显示标签指定给计算或派生的数据列,以替换缺省列头expression。在图1、图 3和图1中,派生数据显示在expression列中。下列查询还显示派生值,但显示派生值的列 具有描述性头taxed。

图查询

SELECT stock_num, description, unit_price,

unit_price * 1.07 taxed

FROM stock

WHERE unit_price >= 400;

结果显示将标记taxed指定给用于显示操作unit_price * 1.07的结果的投影列表中的表达 式。

图:查询结果

stock_num description unit_price taxed

1 baseball gloves

$800.00

$856.00

1 baseball gloves

$450.00

$481.50

4 football

$960.00

$1027.20

4 football

$480.00

$513.60

7 basketball

$600.00

$642.00

8 volleyball

$840.00

$898.80

102 bicycle brakes

$480.00

$513.60

111 10-spd, assmbld

$499.99

$534.99

112 12-spd, assmbld

$549.00

$587.43

113 18-spd, assmbld

$685.90

$733.91

203 irons/wedge

$670.00

$716.90

在下列查询中,为显示操作total_price + 6.50的结果的列定义标签surchargeo

图查询

SELECT item_num, order_num, quantity,

total_price, total_price + 6.50 surcharge

FROM items

WHERE quantity < 5;

在输出中对surcharge列添加标签。

图:查询结果

item_num order_num quantity total_price surcharge

1

1001

1

$250.00

$256.50

1

1002

1

$960.00

$966.50

2

1002

1

$240.00

$246.50

1

1003

1

$20.00

$26.50

2

1003

1

$840.00

$846.50

1

1023

2

$40.00

$46.50

2

1023

2

$116.00

$122.50

3

1023

1

$80.00

$86.50

4

1023

1

$228.00

$234.50

5

1023

1

$170.00

$176.50

6

1023

1

$190.00

$196.50

下列查询将标签span指定给显示从DATETIME列res_dtime减去DATETIME 列call_dtime的结果的列。

图查询

SELECT customejnum, call_code, call_dtime,

res_dtime - call_dtime span

FROM cust_calls ORDER BY customer_num;

在输出中标记了 span列。

图: 查询结果

customejnum call_code call_dtime

span

106 D

1998-06-12 08:20

0 00:05

110 L

1998-07-07 10:24

0 00:06

116 I

1997-11-28 13:34

0 03:13

116 I

1997-12-21 11:24

5 20:55

119 B

1998-07-01 15:00

0 17:21

121 O

1998-07-10 14:05

0 00:01

127 I

1998-07-31 14:30

CASE表达式

CASE表达式条件表达式,类似于编程语言中的CASE语句。当要更改表示数据的方式时, 可以使用CASE表达式。CASE表达式允许语句返回若干可能结果之一,这取决于若干条 件测试中哪一个求值为TRUE。

在CASE表达式中不允许TEXT或BYTE值。

考虑用数字表示婚姻状态的列,1、2、3和4是相应表示单身、已婚、离异和丧偶的值。 在某些情况下,考虑到数据库的效率,您可能更想存储短的值(1 ,2,3和4),但人

力资源部的职员可能更具有描述性的值(单身、已婚、离异和丧偶)。CASE表达式简化 了这种不同值集之间的转换。

下列示例显示具有多个 WHEN子句的CASE表达式,它返回stock表的manu_code列更 具有描述性的值。如果没有任何WHEN条件为true,那么NULL是缺省的结果。(可以 省略ELSE NULL子句。)

SELECT

CASE

WHEN manu_code = “HRO” THEN “Hero”

WHEN manu_code = “SHM” THEN “Shimara”

WHEN manu_code = “PRC” THEN “ProCycle”

WHEN manu_code = “ANZ” THEN “Anza”

ELSE NULL

END

FROM stock;

在CASE表达式中必须至少包含一个 WHEN子句;后续的WHEN子句和ELSE子句 是可选的。如果没有WHEN条件求值为true,那么结果值为NULL。可以使用IS NULL 表达式来处理为NULL值的结果。有关处理值(NULL)的信息,请参阅《GBase 8s SQL指 南:语法》。

下列查询显示了简单的CASE表达式,它返回一个字符串值来标记0rders表中尚未交付给 客户的任何订单。

图:查询

SELECT order_num, order_date,

CASE

WHEN ship_date IS NULL

THEN “order not shipped”

END

FROM orders;

图:查询结果

ordejnum ordejdate (expression)

05/20/1998
05/21/1998
05/22/1998
05/22/1998
05/24/1998
05/30/1998 order not shipped
05/31/1998
07/11/1998
07/11/1998
07/23/1998
07/24/1998
07/24/1998
有关如何使用CASE表达式来更新列的信息,请参阅更新列的CASE表达式。

对派生列进行排序

当想要在表达式中使用ORDER BY时,可以使用指定给表达式的显示标注或整数。如图1 和图3所示。

图查询

SELECT customejnum, call_code, call_dtime,

res_dtime - call_dtime span

FROM cust_calls ORDER BY span;

下列查询从cust_calls表中检索图5所检索的相同数据。在此查询中,ORDER BY子句导 致以span列中派生值的升序显示数据,如下所示。

图: 查询结果

customejnum call_code call_dtime span

127 I

1998-07-31 14:30

121 O

1998-07-10 14:05

0 00:01

106 D

1998-06-12 08:20

0 00:05

110 L

1998-07-07 10:24

0 00:06

116 I

1997-11-28 13:34

0 03:13

119 B

1998-07-01 15:00

0 17:21

116 I

1997-12-21 11:24

5 20:55

下列查询使用整数表示运算res_dtime - call_dtime的结果,并检索出现在上一结果中的相同 行。

图查询

SELECT customer_num, call_code, call_dtime,

res_dtime - call_dtime span

FROM cust_calls ORDER BY 4;

3.2.8在SELECT语句中使用Rowid值

数据库服务器将唯一的rowid指定给未分片的表中的行。实际上,rowid是每个表中的隐藏 列。rowid的顺序值没有任何特殊意义,可能根据chunk中的物理数据的位置的不同而变 化。可以使用rowid来找到与表中的某行相关联的内部记录号。分片表中的行不自动包含 rowid 列。

建议您在应用程序中使用主键而不是rowid作为访问的方法。因为主键是用SQL的 ANSI规范定义的,所以使用它们来访问数据提高了应用程序的可移植性。另外,当数据 库服务器使用主键时,它访问分片表中的数据所需的时间比使用rowid时访问相同数据所 需的时间要要少。

有关rowid的更多信息,请参阅《GBase 8s管理员指南》。

下列查询在Projection子句中使用rowid和星号(*)来检索manufact表中的每一行及其 相应的rowid o

图查询

SELECT rowid, * FROM manufact;

图:查询结果

rowid manu_code manu_name

lead_time

257 SMT

Smith

3

258 ANZ

Anza

5

259 NRG

Norge

7

260 HSK

Husky

5

261 HRO

Hero

4

262 SHM

Shimara

30

263 KAR

Karsten

21

264 NKL

Nikolus

8

265 PRC

ProCycle

9

不要在permanent表中存储rowid或尝试将它用作外键。如果删除了一个表然后从外部数 据重新装入它,那么所有rowid都将不同。

3.3多表SELECT语句

要从两个或多个表中选择数据,在FROM子句中指定表名。添加WHERE子句一章每个 表中的至少一个相关列间创建连接条件。WHERE子句创建临时组合表。在其中,满足连 接添加的每一对行都被链接以组成单个行。

简单连接根据每个表中某列的关系组合来自两个或多个表的信息。组合连接根据每个表中 两个或多个列之间的关系连接两个或多个表。

要创建连接,必须在每个表中至少一列之间指定称为连接条件的关系。因为要对列进行比 较,所以它们必须具有兼容的数据类型。当连接大型表时,对连接条件中的列进行索引会 提高性能。

数据类型在GBase 8s SQL参考指南中描述。索引在GBase 8s管理员指南中详细所讨论。

3.3.1创建笛卡尔积

当执行未显式声明表之间的连接条件的多表查询时,就创建了笛卡尔积。笛卡尔积由表的 行的每种可能的组合构成。此结果通常很大且不实用。

以下查询从两个表中进行选择并生成笛卡尔积。

图:查询

SELECT * FROM customer, state;

state表只有52行,customer表只有28行,然而查询的影响是将一个表的行数乘以另一 个表的行数并检索不实用的1,456行,如下所示。

图:查询结果

customejnum 101

fname

Ludwig

lname

Pauli

company

All Sports Supplies

address1

213 Erstwild Court

address2

city

Sunnyvale

state

CA

zipcode

94086

phone

408-789-8075

code

AK

sname

Alaska

customer_num 101 fname Ludwig

Iname Pauli

company All Sports Supplies

address1 213 Erstwild Court

address2

city Sunnyvale

state CA

zipcode 94086

phone 408-789-8075

code HI

sname Hawaii

customer_num 101

fname

Ludwig

lname

Pauli

company

All Sports Supplies

address1

213 Erstwild Court

address2

city

Sunnyvale

state

CA

zipcode

94086

phone

408-789-8075

code

CA

sname

California

另外,显示在连续行中的某些数据是矛盾的。例如:虽然customer表中的city和state指示 在California的地址,但是state表的code和sname可能是另一个州的。

3.3.2创建连接

在概念上,任何连接的第一阶段是创建笛卡尔积,要改进或限制此笛卡尔积并除去数据行 的无意义组合,在SELECT语句的WHERE子句中包括有效的连接条件。

本节说明了跨连接、等值连接、自然连接和多表连接。其他复杂构成(如自连接和外链接) 在编写高级SELECT语句中讨论。

跨连接

跨连接组合所有选择的表中的所有行并创建笛卡尔积。跨连接的结果可能会非常大并且难 于管理。

下列查询使用ANSI连接语法创建跨连接。

图:查询

SELECT * FROM customer CROSS JOIN state;

该查询的结果与图1的结果完全相同。另外,可能通过指定WHERE子句来过滤跨连接。

有关笛卡尔积的更多信息,请参阅创建笛卡尔积。有关ANSI语法的更多信息,请参阅ANSI 连接语法。

等值连接

等值连接是基于相等或匹配列值的连接。在WHERE子句中,使用作为比较运算符的等号 (=)来表示这一相等关系。如下所示。

图:查询

SELECT * FROM manufact, stock

WHERE manufact.manu_code = stock.manu_code;

该查询在manu_code列上连接manufact和stock表。它只检索两个列的值相等的那些行。 以下结果显示了一些这样的行。

图:查询结果

manu_code SMT

manu_name Smith

lead_time 3

stock_num 1

manu_code SMT

description baseball gloves

unit_price $450.00

unit

case

unit_descr

10 gloves/case

manu_code

SMT

manu_name

Smith

lead_time

3

stock_num

5

manu_code

SMT

description

tennis racquet

unit_price

$25.00

unit

each

unit descr

each

manu_code

SMT

manu_name

Smith

lead_time

3

stock_num

6

manu_code

SMT

description

tennis ball

unit_price

$36.00

unit

case

unit_descr

24 cans/case

manu_code

ANZ

manu_name

Anza

lead_time

5

stock_num

5

manu_code

ANZ

description

tennis racquet

unit_price

$19.80

unit

each

unit_descr

each

在等值连接中,该结果同时包括manufact和stock表中的manu_code列,原因是选择列表 请求每个列。

还可以使用附加约束创建等值连接,此时比较条件基于连接列中值的不相等性。这些连接 在WHERE子句中指定的比较条件中除等号(=)之外还使用其他关系运算符。

要连接包含相同名称的列的表,用列的表名和句点(.)限定每个列名,如下列查询所示。

图查询

SELECT order_num, orde^date, ship_date, cust_calls.*

FROM orders, cust_calls

WHERE call_dtime >= ship_date

AND cust_calls.customer_num = orders.customer_num

ORDER BY orders.customejnum;

该查询连接customer_num列,然后只选择cust_calls表中call_dtime大于或等于orders表中 的ship_date那些行。该结果显示它返回的组合行。

图:查询结果

order_num 1004

order_date 05/22/1998

ship_date 05/30/1998

customer_num 106

call_dtime 1998-06-12 08:20

user_id maryj

call_code D

call_descr Order received okay, but two of the cans of

ANZ tennis balls within the case were empty

res_dtime 1998-06-12 08:25

res_descr Authorized credit for two cans to customer,

issued apology. Called ANZ buyer to report

the qa problem.

order_num

1008

order_date

06/07/1998

ship_date

07/06/1998

customer_num

110

call_dtime

1998-07-07 10:24

user_id

richc

call_code

L

call_descr

Order placed one month ago (6/7) not received.

res_dtime

1998-07-07 10:30

res_descr

Checked with shipping (Ed Smith). Order out

yesterday-was waiting for goods from ANZ. Next time will call with delay if necessary.

order_num order_date ship_date

1023

07/24/1998

07/30/1998

customer_num 127

call_dtime user_id

1998-07-31 14:30

maryj

call_code call_descr

I

Received Hero watches (item # 304) instead

of ANZ watches

res_dtime res_descr

Sent memo to shipping to send ANZ item 304

to customer and pickup HRO watches. Should be done tomorrow, 8/1

自然连接

自然连接是等值连接的一种,构建它来使连接列不会多余地显示数据,如以下查询所示。

图查询

SELECT manu_name, lead_time, stock.*

FROM manufact, stock

WHERE manufact.manu_code = stock.manu_code;

类似等值连接的示例,该查询在manu_code列上连接manufact和stock表。因为更接近地 定义了投影列表,所以只对检索到的每一行列出一次manu_code,如下所示。

图:查询结果

manu_name Smith

lead_time

3

stock_num

1

manu_code

SMT

description

baseball gloves

unit_price

$450.00

unit

case

unit_descr

10 gloves/case

manu_name

Smith

lead_time

3

stock_num

5

manu_code

SMT

description

tennis racquet

unit_price

$25.00

unit

each

unit_descr

each

manu_name

Smith

lead_time

3

stock_num

6

manu_code

SMT

description

tennis ball

unit_price

$36.00

unit

case

unit_descr

24 cans/case

manu_name Anza

lead_time 5

stock_num 5 manu_code ANZ

description tennis racquet

unit_price $19.80 unit each

unit_descr each

所有的连接都是相关联的。即,WHERE子句中的连接术语不影响连接的意义。

下列查询中的两个语句都创建相同的自然连接。

图查询

SELECT catalog.*, description, unit_price, unit, unit_descr

FROM catalog, stock

WHERE catalog.stock_num = stock.stock_num

AND catalog.manu_code = stock.manu_code

AND catalog_num = 10017;

SELECT catalog.*, description, unit_price, unit, unit_descr

FROM catalog, stock

WHERE catalog_num = 10017

AND catalog.manu_code = stock.manu_code

AND catalog.stock_num = stock.stock_num;

每个语句检索到下列行。

图:查询结果

catalog_num 10017

stock_num 101

manu_code PRC

cat_descr

Reinforced, hand-finished tubular. Polyurethane belted.

Effective against punctures. Mixed tread for super wear and road grip.

cat_picture

cat_advert Ultimate in Puncture Protection, Tires

Designed for In-City Riding description bicycle tires unit_price $88.00 unit box

unit_descr 4/box

图 3 包括 TEXT 列 cat_descr、BYTE 列 cat_picture 和 VARCHAR 列 cat_advert。

多表连接

多表连接在一个或多个相关联列上连接两个以上的表。它可以是等值连接或自然连接。

下列查询在catalog、stock和manufact表上创建等值连接。

图查询

SELECT * FROM catalog, stock, manufact

WHERE catalog.stock_num = stock.stock_num

AND stock.manu_code = manufact.manu_code

AND catalog_num = 10025;

该查询检索到下列行。

图: 查询结果

catalog_num 10025

stock_num 106

manu_code PRC

cat_descr

Hard anodized alloy with pearl finish; 6mm hex bolt hard ware.

Available in lengths of 90-140mm in 10mm increments.

cat_picture

cat_advert

ProCycle Stem with Pearl Finish

stock_num

106

manu_code

PRC

description

bicycle stem

unit_price

$23.00

unit

each

unit_descr

each

manu_code

PRC

manu_name

ProCycle

lead_time

9

manu_code重复三次,每个表一次,stock_num重复两次。

为避免多表查询的大量重复(如图1),在投影列表中包括特定的列以更确切地定义 SELECT语句,如下所示。

图查询

SELECT catalog.*, description, unit_price, unit,

unit_descr, manu_name, lead_time

FROM catalog, stock, manufact

WHERE catalog.stock_num = stock.stock_num

AND stock.manu_code = manufact.manu_code

AND catalog_num = 10025;

该查询使用通配符来从具有大多数列的表中选择所有列,然后从其他两个表中指定列。下 表显示了此查询生成的自然连接。它与前一示例显示相同的信息,但不重复。

图:查询结果

catalog_num 10025

stock_num 106

manu_code PRC

cat_descr

Hard anodized alloy with pearl finish. 6mm hex bolt

hardware. Available in lengths of 90-140mm in 10mm increments.

cat_picture

cat_advert

ProCycle Stem with Pearl Finish

description

bicycle stem

unit_price

$23.00

unit

each

unit_descr

each

manu_name

ProCycle

lead_time

9

3.3.3某些查询快捷方式

可以使用别名,INTO TEMP子句和显示标注来加快连接和多表查询,并生成输出以用于 其它用途。

别名

可以在SELECT语句的FROM子句中将别名指定给表,以使多表查询更节省时间,可读 性更高。每当要使用表名时,就可以使用别名,例如:在其他子句中作为列名的前缀。

图查询

SELECT s.stock_num, s.manu_code, s.description,

s.unit_price, c.catalog_num,

c.cat_advert, m.lead_time

FROM stock s, catalog c, manufact m

WHERE s.stock_num = c.stock_num

AND s.manu_code = c.manu_code

AND s.manu_code = m.manu_code

AND s.manu_code IN (‘HRO’, ‘HSK’)

AND s.stock_num BETWEEN 100 AND 301

ORDER BY catalog_num;

SELECT语句的相关特性允许您在定义别名之前使用别名。在此查询中,stock表的别名 是s, catalog表的别名是c, manufact表的别名是m,它们分别在FROM子句中指定。并 在整个SELECT和 WHERE子句中用作列前缀。

将图1的长度与下列查询比较,后者不使用别名。

图查询

SELECT stock.stock_num, stock.manu_code, stock.description, stock.unit_price, catalog.catalog_num,

catalog.cat_advert, manufact.lead_time FROM stock, catalog, manufact

WHERE stock.stock_num = catalog.stock_num

AND stock.manu_code = catalog.manu_code

AND stock.manu_code = manufact.manu_code

AND stock.manu_code IN (‘HRO’, ‘HSK’)

AND stock.stock_num BETWEEN 100 AND 301

ORDER BY catalog_num;

图1和图2是等价的且都检索到以下查询显示的数据。

图:查询结果

stock_num 110

manu_code HRO

description helmet unit_price $260.00 catalog_num 10033

cat_advert Lightweight Plastic with Vents Assures Cool

Comfort Without Sacrificing Protection

lead_time 4

stock_num 110

manu_code HSK

description helmet unit_price $308.00 catalog_num 10034

cat_advert Teardrop Design Used by Yellow Jerseys; You

Can Time the Difference

lead_time 5

不能将 ORDER BY 子句用于 TEXT 列 cat_descr 或 BYTE 列 cat_picture。

可以使用别名来缩短对不在当前数据库中的表的查询时间。

下列查询连接驻留在不同数据库和系统(均不是当前数据库或系统)中的2个表中的列。

图查询

SELECT order_num, Iname, fname, phone

FROM masterdb@central:customer c, sales@western:orders o

WHERE c.customer_num = o.customer_num

AND order_num <= 1010;

通过分别将c和o指定给长database@system:table名

称 masterdb@central:customer 和 sales@western:orders,您可以使用别名来缩短 WHERE 子 句中的表达式并检索数据,如下所示。

图:查询结果

ordejnum lname

fname

phone

1001 Higgins

Anthony

415-368-1100

1002 Pauli

Ludwig

408-789-8075

1003 Higgins

Anthony

415-368-1100

1004 Watson

George

415-389-8789

1005 Parmelee

Jean

415-534-8822

1006 Lawson

Margaret

415-887-7235

1007 Sipes

Arnold

415-245-4578

1008 Jaeger

Roy

415-743-3611

1009 Keyes

Frances

408-277-7245

1010 Grant

Alfred

415-356-1123

有关如何访问不在当前数据库中的表的更多信息,请参阅访问其他数据库服务器和《GBase 8s SQL指南:语法》。

还可以使用同义词作为不在当前数据库中的表以及当前表和视图的长名称的简写引用。

INTO TEMP 子句

通过将INTO TEMP子句添加到您的SELECT语句,可以在独立的表中临时保存多表查 询的结果,您可以查询或处理该表,而无需修改数据库。当结束SQL会话或者程序或报 告终止时,就会删除临时表。

下列查询创建名为stockman的临时表,并将在其中保存查询的结果。由于临时表中的所有 列都必须具有名称,所以别名adj_price是必需的。

图:查询

SELECT DISTINCT stock_num, manu_name, description,

unit_price, unit_price * 1.05 adj_price

FROM stock, manufact

WHERE manufact.manu_code = stock.manu_code

INTO TEMP stockman;

SELECT * from stockman;

图:查询结果

stock_num manu_name description unit_price adj_price

1 Hero

baseball gloves

$250.00

$262.5000

1 Husky

baseball gloves

$800.00

$840.0000

1 Smith

baseball gloves

$450.00

$472.5000

2 Hero

baseball

$126.00

$132.3000

3 Husky

baseball bat

$240.00

$252.0000

4 Hero

football

$480.00

$504.0000

4 Husky

football

$960.00 $1008.0000

306 Shimara

tandem adapter

$190.00

$199.5000

307 ProCycle

infant jogger

$250.00

$262.5000

308 ProCycle

twin jogger

$280.00

$294.0000

309 Hero

ear drops

$40.00

$42.0000

309 Shimara

ear drops

$40.00

$42.0000

310 Anza

kick board

$84.00

$88.2000

310 Shimara

kick board

$80.00

$84.0000

311 Shimara

water gloves

$48.00

$50.4000

312 Hero

racer goggles

$72.00

$75.6000

312 Shimara

racer goggles

$96.00

$100.8000

313 Anza

swim cap

$60.00

$63.0000

313 Shimara

swim cap

$72.00

$75.6000

可以查询此表并将该表与其它表连接,这可以避免多次排序,并使您能够更快地在数据库 中移动。有关临时表的更多信息,请参阅《GBase 8s SQL指南:语法》和《GBase 8s管理 员指南》。

3.4总结

本章介绍了用于查询关系数据库的基本SELECT语句类型的语法示例和结果。单个表的SELECT语句一节显示了如何执行以下操作:

使用Projection和FROM子句从表中选择列和行
使用Projection、FROM和 WHERE子句从表中选择行
在Projection子句中使用DISTINCT或UNIQUE关键字来消除查询结果中重复的行
使用ORDER BY子句和DESC关键字来排序检索的数据
•     选择包含非英语字符的数据值并对其排序

在 WHERE子句中使用BETWEEN、IN、MATCHES和LIKE关键字以及各
种关系运算符来创建比较条件

•      创建包括值、排除值、查找一定范围内的值(使用关键字、关系运算符和下标)查找值的子集的比较条件

•      使用精确文本比较、变长通配符和受限及非受限通配符来执行变量文本搜索

使用逻辑运算符AND、OR和NOT来在WHERE子句中连接搜索条件或Boolean表达式
•      使用ESCAPE关键字来保护查询中的特殊字符

在 WHERE子句中使用IS NULL和IS NOT NULL关键字来搜素NULL值
使用FIRST子句指定查询只返回符合SELECT语句的条件的指定书目的行
•      在Projection子句中使用算术运算符对数字字段执行计算并显示派生数据

•      将显示标签指定个计算列作为用于报告的格式化工具

本章还介绍了简单连接条件,使您能够从两个或多个表中选择和显示数据。多表SELECT语句一节描述了如何执行下列操作:

•创建笛卡尔积

创建CROSS JOIN,它创建笛卡尔积
•在查询中将WHERE子句与有效连接条件包括在一起以抑制笛卡尔积

•定义和创建自然连接和等值连接

•在一列或多列上连接两个或多个表

•在多表查询中使用别名作为快捷方式

•使用INTO TEMP子句将选择的数据检索到独立的临时表中,以便在数据库外部执行计算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值