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子句将选择的数据检索到独立的临时表中,以便在数据库外部执行计算