返回首页

gbase数据、南大通用产品文档:GBase8sSELECT 语句

更新日期:2024年09月11日

使用 SELECT 语句来从数据库或从 SPL 或 GBase 8s ESQL/C 集合变量检索
值。SELECT 操作称为查询。
满足该查询的特定的查询条件的行或值称为符合条件的行或值。在应用任何附加
的逻辑条件之后,该查询检索到的其调用上下文称为该查询的结果集。此结果集
可为空。
语法

Select 选项

元素
描述
限制
语法
column 在 FETCH 之后可被
更新的列的名称
必须在 FROM 子句表中,但不需要在
Projection 子句的选择列表中
标识符
用法

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 850
SELECT 语句可从当前数据库中,或当前数据库服务器的另一数据库中,或另一
数据库服务器的数据库中的表返回数据。 仅 SELECT 关键字、Projection 子句
和 FROM 子句是必需的规范。
对于包括 CONNECT BY 子句的层级查询,FROM 子句仅可指定单个表,该表必
须驻留在连接到当前会话的 GBase 8s 数据库服务器实例的本地数据库中。
对于包括 GRID 子句的查询,在 GRID 子句指定的每个节点上,FROM 子句指
定的每一表的实例必须有相同的模式、相同的数据库语言环境和相同的代码集。
SELECT 语句只能引用 CREATE EXTERNAL TABLE 语句已指定的一个外部
表。在复合查询中,仅可在最外部的查询中指定此外部表。您不可在子查询中引
用外部表。
您需要对该数据库的 Connect 访问权限来执行查询,以及对该查询要从其检索行
的表对象的 Select 权限。
SELECT 语句可包括各种基本的子句,标识在下列列表中。
子句
作用
优化程序伪指令
指定该查询应如何实现
Projection 子句
指定要从数据库读的项的列表
INTO 子句
指定接收结果集的变量
FROM 子句
指定 Projection 子句项的数据源
表或视图的别名
查询中表或列的临时名称
表表达式
定义派生的表作为查询数据源
横向的派生的表
定义查询中相关联的表引用
ONLY 关键字
排除孩子表作为类型表的查询中的数据源
迭代器函数
反复地返回值作为数据源的函数
符合 ANSI 的连接
符合 ISO/ANSI 语法标准的连接查询
GBase 8s 扩展外连

基于隐式的 LEFT OUTER 连接的查询语法

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 851
子句
作用
GRID 子句
指定存储网格查询的表的节点
使用 ON 子句
指定连接条件作为连接前过滤器
SELECT 的 WHERE
子句
对符合条件的行和连接后过滤器设置条件
层级查询子句
为层级数据的查询设置条件
GROUP BY 子句
将行的组组合到汇总结果内
HAVING 子句
对汇总结果设置条件
ORDER BY 子句
根据列值对符合条件的行排序
ORDER SIBLINGS BY
子句
在每个级别为兄弟层级数据排序
FOR UPDATE 子句
在 FETCH 之后启用结果集的更新
FOR REArD ONLY 子

在 FETCH 之后禁用结果集的更新
INTO TEMP 子句
将结果集放到临时表内
INTO EXTERNAL 子

在外部表中存储查询结果集
INTO STANDARD 和
INTO RAW 子句
在永久数据库表中存储查询结果集
UNION ALL 运算符
组合两个 SELECT 语句的结果集
UNION 运算符
与 UNION ALL 相同,但废弃重复的行
INTERSECT 运算符
从两个查询结果集返回不同的公共行
MINUS 运算符
仅返回两个查询返回的第一个不同的行。
接下来的部分描述这些和 SELECT 语句的其他子句。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 852
Projection 子句
Projection 子句(有时称为Select 子句)指定要检索的数据库对象或表达式的列
表,并可设置对符合条件的行的限制。(select 列表有时也称为 projection 列
表。)
Projection 子句

Select 列表

元素
描述
限制
语法
alias
临时表或视图名称。
请参阅 FROM 子句。
仅当 FROM 子句为
table 或 view 声明
alias 时才有效
标识符
column_alias
您在此为 column 声
明的临时标识符
在此查询中的 columns
和 column_alias 名称
之中必须是唯一的。仅
标识符

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 853
元素
描述
限制
语法
GROUP BY 子句可引用
column_alias。
column
从其检索数据的列
在 FROM 子句引用的数
据源中必须存在
标识符
display_label
在此为 column 或为
表达式声明的临时名

请参阅 声明显示标签
标识符
external
从其检索数据的外部

必须存在
数据库对
象名
max
指定要返回的行的最
大数目的整数(> 0)
如果 max > 符合条件
的行的数目,则返回所
有相匹配的行
精确数值
max_var
存储 max 的值的主变
量或本地 SPL 变量
与 max 相同;在准备
好的对象和 SPL 例程
中有效
依赖于语

offset
指定在结果集的第一
行之前要排除多少符
合条件的行的整数(>
0)
不可为负数。如果
offset > (符合条件
的行的数目),则不返
回行
精确数值
off_var
存储偏移量的值的主
变量或本地 SPL 变量
与 offset 相同;在准
备好的对象和在用户定
义的例程中有效
依赖于语

subquery
嵌入的查询
在 Projection 子句之
内的子查询不可包括
SKIP、FIRST、INTO
TEMP 或 ORDER BY 子
句。
SELECT 语


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 854
元素
描述
限制
语法
table, view,
synonym
要从其检索数据的
表、视图或同义词的
名称
同义词以及它执行的表
或视图必须存在
数据库对
象名
星号(*)指定按照其定义的顺序在表或视图中的所有列。要以另一顺序存取所有
列或列的子集,您必须显式地指定单独的 column 名称。如果 FROM 子句仅指
定单个数据源,则单个的星号(*)可为有效的 Projection 子句。
SKIP、FIRST、LIMIT、MIDDLE、DISTINCT 和 UNIQUE 规范可将结果限定到
符合条件的行的子集,如以下部分所解释。
符合条件的行的顺序
要执行查询,数据库服务器构建查询计划并检索与 WHERE 子句条件相匹配的所
有符合条件的行。(此处,行指的是值的一个集合,如在 select 列表中指定的那
样,来自 FROM 子句指定的表或连接的表的单个记录。)如果该查询没有
ORDER BY 子句,则符合条件的行按照它们的检索的顺序排列,每一执行可能都
不一样;否则,它们的排列遵循 ORDER BY 规范,如 ORDER BY 子句 中描述
的那样。
如果 Projection 子句包括任何下列选项,则查询是否指定 ORDER BY 可影响到
哪些行在结果集中:

FIRST 选项

SKIP 和 LIMIT 选项
使用 SKIP 选项
SKIP offset 选项指定要排除多少符合条件的行,对于 offset SERIAL8 范围内
的一个整数,从符合条件的第一行计数。下列示例从除了前 10 行之外的所有行
检索值:
SELECT SKIP 10 a, b FROM tab1;
您还可使用主变量来指定要排除多少行。在 SPL 例程中,您可使用输入参数或本
地变量来提供此值。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 855
当您以 ORDER BY 子句在查询中使用 SKIP 选项时,可排除前 offset 行,根
据 ORDER BY 条件这些行有最低的值。如果 ORDER BY 子句包括 DESC 关键
字,则您还可使用 SKIP 来排除带有最高值的行。例如,下列查询返回 orders
表的所有行,除了最旧的 50 个订单之外:
SELECT SKIP 50 * FROM orders ORDER BY order_date;
在此,如果在 orders 表中只有不到 50 行,则结果集为空。offset = 0 不是无
效,但在那种情况下,SKIP 选项无作用。
您还可使用 SKIP 选项来限制准备好了的 SELECT 语句的、UNION 查询的结果
集,在其结果集定义集合派生的表的查询中,以及在触发器的事件或活动中。
您可以一起使用 SKIP 与 FIRST 选项来指定在结果集中的哪些以及多少符合条
件的行,如在 使用带有 FrIRST 选项的 SKIP 选项 部分中的示例展示的那样。
SKIP 在下列上下文中无效:

在视图的定义中

在嵌套的 SELECT 语句中

在子查询中。
使用 FIRST 选项
FIRST max 选项指定结果集包括不多于 max 行(或正好 max,如果 max 不大于
符合条件的行的数目的话)。 不返回满足选择条件的任何附加的行。下例最多从
表 tab1 检索 10 行:
SELECT FIRST 10 a, b FROM tab1;
GBase 8s 可使用主变量或在本地变量中指定 max 的 SPL 输入参数的值。
随同 ORDER BY 子句,您可检索符合条件的行的前 max 行。例如,下列查询找到
薪酬最高的 10 名雇员:
SELECT FIRST 10 name, salary FROM emp ORDER BY salary DESC;
您可使用在查询中的 FIRST 选项,该查询的结果集在另一 SELECT 语句的 FROM
子句之内定义集合派生的表(CDT)。下列查询指定有不多于 10 行的 CDR:
SELECT *
FROM TABLE(MULTISET(SELECT FIRST 10 * FROM employees

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 856
ORDER BY employee_id)) vt(x,y), tab2
WHERE tab2.id = vt.x;
在 FROM 子句中包括表表达式的查询中,FIRST 和 SKIP 关键字还有效:
SELECT * FROM (SELECT SKIP 2 FIRST 8 col1 FROM tab1 WHERE col1 >
50 );
下一示例将 FIRST 选项用于 UNION 表达式的结果:
SELECT FIRST 10 a, b FROM tab1 UNION SELECT a, b FROM tab2;
在任何下列上下文中,FIRST 选项都无效:

在视图的定义中

在嵌套的 SELECT 语句中

在子查询中,除了在 FROM 子句中指定表表达式的那些子查询之外

在 SPL 例程之内的单 SELECT 中(此处 max = 1)

将嵌套的 SELECT 语句用作表达式的情况下
LIMIT 关键字
LIMIT 是在 Projection 子句中 FIRST 关键字的关键字同义词。然而,您不可在
FIRST 为有效的其他语法上下文中以 LIMIT 替换 FIRST,比如在 FETCH 语句
中。
使用 TOP 选项
TOP 选项支持以下两种方式:

TOP N :指定取得结果集中前 N 条记录。

TOP M,N :指定取得结果集中第 M 条记录之后的 N 条记录。
您可检索前 N 个符合条件的行。例如,下列查询将找到薪酬最高的 10 名雇员:
SELECT TOP 10 name, salary FROM employee ORDER BY salary DESC;
下列查询将找到薪酬第二高的雇员:
SELECT TOP 1,1 name, salary FROM employee ORDER BY salary DESC;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 857
使用 SKIP、FIRST、TOP、LIMIT 或 MIDDLE 作为列名

如果没有整数紧跟在 FIRST 关键字之后,则数据库服务器将 FIRST 解释为列标
识符。例如,如果表 T 有列 first、second 和 third,则下列查询会从名为
first 的列返回数据:
SELECT first FROM T
同样的考虑也适用于TOP、SKIP 和 LIMIT 关键字。如果 Projection 子句中的
LIMIT 关键字之后没有字面整数也没有整数变量,则 GBase 8s 将 LIMIT 解释
作为列名称。如果 FROM 子句中的数据源不具有带有该名称的列,则查询失败
并报错。
使用带有 FIRST 选项(或 TOP 选项)的 SKIP 选项
如果带有 SKIP offset 选项的 Projection 子句还包括 FIRST 、TOP 或 LIMIT,
则结果集将以符合条件的行集合中顺序位置为(offset + 1)的行开始,而不是以
第一行开始。除非符合条件的行少于(offset + max),否则位置(offset +
max)上的行是结果集中的最后一行,。下列示例忽略了表 tab1 的前50 行,但
返回最多 10 行的结果集,以第 51 行开始:
SELECT SKIP 50 FIRST 10 a, b FROM tab1;
下一示例在查询中使用 SKIP 和 FIRST 来将不多于 5 行从表 tab1 插入到表
tab2 内,以第 11 行开始:
INSERT INTO tab2 SELECT SKIP 10 FIRST 5 * FROM tab1;
也可以使用 TOP 关键字代替 FIRST 关键字,以下示例的效果等同于上一示例:
INSERT INTO tab2 SELECT SKIP 10 TOP 5 * FROM tab1;
下列集合子查询仅返回第 11 至第 15 之间的符合条件的行作为集合派生的表,
通过列 a 中的值排列这 5 行的顺序,并将此结果集存储在临时表中。
SELECT * FROM TABLE (MULTISET
(SELECT SKIP 10 FIRST 5 a FROM tab3
ORDER BY a)) INTO TEMP;
下列 INSERT 语句包含一个集合子查询,该集合子查询的结果将定义集合派生
表。这些行按列 a 中的值排列顺序,并将插入到表 tab1 内。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 858
INSERT INTO tab1 (a)
SELECT * FROM TABLE (MULTISET (SELECT SKIP 10 FIRST 5 a
FROM tab3 ORDER BY a));
将 FIRST 或 LIMIT 或 TOP 和 SKIP 选项与 ORDER 子句结合在一起的查询
可对符合条件的行强加唯一顺序,因此按 max 的值增大 offset 值的连续查询可
将符合条件的行划分为max 行的不相连子集。这可支持需要固定页面大小的 web
应用程序,而无需游标管理。
仅当所有参与的数据库服务器都支持 SKIP 和 FIRST 选项(或 TOP 选项),
您才可在分布式查询中使用这些特性。
允许重复
您可应用 ALL、UNIQUE 或 DISTINCT 关键字来指示是否返回重复的值,如果
存在的话。如果您在 Projection 子句中未指定任何这些关键字,则在缺省情况下
返回所有符合条件的行。
关键字 作用
ALL 指定返回所有符合条件的行,不论是否存在重复。(这是缺省的
规范。)
DISTINCT 从结果集排除重复的符合条件的行
UNIQUE 排除重复。(此处 UNIQUE 是 DISTINCT 的同义词。这是对
ANSI/ISO 标准的扩展。)
例如,下一查询返回从 items 的行中的 stock_num 和 manu_code 列的所有唯一
的有顺序的值对。如果几行有相同的值对,则那个值对仅在结果集中显示一次:
SELECT DISTINCT stock_num, manu_code FROM items;
要获得数据库服务器如何标识在有 NLCASE INSENSITIVE 属性的数据库中重复
的 NCHAR 和 NVARCHAR 值的信息,请参阅 在区分大小写的数据库中的
NCHAR 和 NVARCHAR 表达式。
在每一查询或子查询级别内,您可指定 SELECT 语句的 DISTINCT 或 UNIQUE
关键字不超过一次。 下列示例在查询和子查询中都使用 DISTINCT :
SELECT DISTINCT stock_num, manu_code FROM items

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 859
WHERE order_num = (SELECT DISTINCT order_num FROM orders
WHERE customer_num = 120);
上述示例是有效的,因为在每一 SELECT 语句中使用 DISTINCT 未超过一次。
如果查询在 Projection 子句中包括 DISTINCT 或 UNIQUE 关键字(而不是
ALL 关键字或无关键字),该子句的 Select 列表还包括一个其参数列表以
DISTINCT 或 UNIQUE 开头的合计函数, 则数据库服务器发出错误,如下例所
示:
SELECT DISTINCT COUNT(DISTINCT ship_weight)
FROM orders;
即,对于 Projection 子句,以及对于将结果集限制为唯一值的合计函数,它在同
一查询中是无效的。(在上例中,以 UNIQUE 替换 DISTINCT 关键字中的一个
不能避免此错误。)
以多个合计表达式的查询
如果 Projection 子句不指定 SELECT 语句的 DISTINCT 或 UNIQUE 关键字,
则该查询可包括多个内建的合计函数,每一函数包括 DISTINCT 或 UNIQUE 关
键字作为参数列表中的第一个规范,如下例所示:
SELECT COUNT (DISTINCT customer_num),
COUNT (UNIQUE order_num),
AVG(DISTINCT ship_charge) FROM orders;
在同一查询级别中,对 DISTINCT 或 UNIQUE 合计表达式的支持适用于内建的
合计函数,但不适用于 CREATE AGGREGATE 语句定义的用户定义的合计
(UDA)函数。如果在同一查询中多于一个 UDA 表达式的参数列表以
DISTINCT 或 UNIQUE 关键字开头,则数据库服务器发出错误。
在 NLSCASE INSENSITIVE 数据库中重复的行
在以 NLSCASE INSENSITIVE 选项创建的数据库中,NCHAR 或 NVARCHAR
数据类型的列和表达式在大写和小写字母之间没有差别,因此,有相同的字符序
列的这些数据类型的字符串,但有字母大小写区别,取值重复。
在数据库内已加载了相同的字符串,包括 ALL、DISTINCT 或 UNIQUE 关键字
的查询返回的结果可能不同于同一查询从区分大小写的数据句库返回的结果。例
如,在有 NLSCASE INSENSITIVE 属性的数据库中将 NVARCHAR 字符串

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 860
"aCe"、"ACE", 和 "AcE" 算作完全相同的,但在区分大小写的数据库中,同样
的三个字符串会作为不同的值进行处理。
然而,通过使用 ALL、DISTINCT 或 UNIQUE 关键字来包括或排除重复的行,
在 NLSCASE SENSITIVE 和在 NLSCASE INSENSITIVE 数据库中,CHAR、
LVARCHAR 和 VARCHAR 类型的字符串都做相同的处理。要获取更多关于带
有 NLSCASE INSENSITIVE 属性的数据库的信息,请参阅 指定 NLSCASE 区分
大小写 和 在区分大小写的数据库中的 NCHAR 和 NVARCHAR 表达式。
分布式查询中的数据类型
其唯一数据源是会话连接到的本地数据库中的表和视图的那些查询,可从注册在
本地数据库中的任何内建的或用户定义的数据类型的列或表达式返回值。引用其
他数据库中的表或视图的查询称为分布式查询,其它们可访问的数据类型是
GBase 8s 在本地查询中支持的数据类型的子集。
在分布式查询之中,对数据类型的限制依赖于参与的数据库服务器的数目。

如果查询访问的所有数据库都是同一 GBase 8s 实例的数据库,则该查询
称为跨数据库分布式查询。

如果该查询访问多个 GBase 8s 实例的数据库,则该查询称为跨服务器分
布式查询。
在这两类分布式查询中,所有参与的数据库都必须有相同的符合 ANSI/ISO 的状
态。如果所有参与的服务器都支持 SKIP 选项,则跨服务器分布式查询可使用
SKIP 和 FIRST 选项;否则该查询失败并报错。大多数情况下,所有跨服务器操
作需要参与的数据库服务器实例都支持指定该操作的 SQL 语法。
要获取关于分布式查询的附加信息,请参阅 GBase 8s 数据库设计和实现指南。
跨数据库事务中的数据类型
仅访问本地 GBase 8s 实例的数据库的分布式查询(以及其他分布式 DML 操作
或函数调用)可访问下列类别的数据类型:

非 opaque 的内建的数据类型,包括这些:
o
BIGINT
o
BIGSERIAL

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 861
o
BYTE
o
CHAR
o
DATE
o
DATETIME
o
DECIMAL
o
FLOAT
o
INT
o
INTERVAL
o
INT8
o
MONEY
o
NCHAR
o
NVARCHAR
o
SERIAL
o
SERIAL8
o
SMALLFLOAT
o
SMALLINT
o
TEXT
o
VARCHAR

大多数内建的 opaque 数据类型,包括这些:
o
BLOB
o
BOOLEAN
o
CLIENTBINVAL
o
CLOB
o
IFX_LO_SPEC
o
IFX_LO_STAT
o
INDEXKEYARRAY
o
LVARCHAR
o
POINTER
o
RTNPARAMTYPES,
o
SELFUNCARGS
o
STAT

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 862
o
XID

显示地强制转型为上列任何内建的类型的用户定义的类型(UDT)

在前面的列表中任何内建类型的 DISTINCT。
仅当所有 UDT 和 DISTINCT 类型都显式地强制转型为内建的数据类型,本地
GBase 8s 实例的跨数据库分布式操作才可基于内建的数据类型返回 UDT 和
DISTINCT 类型。
在参与该分布式查询中的每一数据库中,所有 opaque UDT、DISTINCT 类型、数
据类型层级和强制转型都必须有完全相同的定义。对于使用上列数据类型作为参
数或作为返回的数据类型的跨服务器 UDR 中的查询或其他 DML 操作,该
UDR 还必须在每一参与的数据库中有相同的定义。
如果跨数据库的分布式查询(或任何其他跨数据库 DML 操作)引用在另一包括任
何下列数据类型的列的 GBase 8s 实例的另一数据库中的表、视图或同义词,则
该分布式查询失败并报错:

LOLIST

IMPEX

IMPEXBIN

SENDRECV

上列的任何 opaque 数据类型的 DISTINCT。

复合的类型(命名的或未命名的 ROW、COLLECTION、LIST、
MULTISET 或 SET)
跨服务器事务中的数据类型
跨两个或多个 GBase 8s 实例的服务器的分布式查询(或任何其他的分布式 DML
操作或函数调用)不可返回复合的或大对象数据类型,也不可返回大多数用户定
义的数据类型(UDT)或 opaque 数据类型。跨服务器分布式查询、DML 操作和
函数调用仅可返回下列数据类型:

任何非 opaque 的内建的数据类型

BOOLEAN

LVARCHAR

非 opaque 的内建的类型的 DISTINCT

BOOLEAN 的 DISTINCT

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 863

LVARCHAR 的 DISTINCT

在此列表中任何出现在上面的 DISTINCT 类型的 DISTINCT。
跨服务器的分布式查询仅可支持 DISTINCT 数据类型,如果显式地将它们强制转
型为内建的类型,且在参与该分布式查询的每一数据库中,则用完全相同的方式
定义所有 DISTINCT 类型、它们的数据类型层级和它们的强制转型。对于那些使
用前面罗列的数据类型作为参数或作为返回的数据类型的查询或其他跨服务器的
UDR 中的 DML 操作,该 UDR 必须在每个参与的数据库中有相同的定义。
存储安全标签对象的内建的 DISTINCT 数据类型 IDSSECURITYLABEL,可由
持有足够的安全凭证的用户跨服务器地和跨数据库操作地对受保护的数据进行访
问。就像对受保护的数据进行本地操作一样,在数据库服务器已经将保护数据安
全的数据的安全标签与发出该查询的用户的安全凭证进行比较之后,访问由安全
策略保护的远程表的那些分布式查询可仅返回 IDSLBACRULES 允许的符合条
件的行。
要获取更过关于在跨数据库 DML 操作中 GBase 8s 支持的数据类型的附加信
息,请参阅 分布式查询中的数据类型。要获取关于在跨服务器操作中有效的
DISTINCT 数据类型的表层级的信息,请参阅 分布式操作中的 DISTINCT 类
型。
如果跨服务器查询(或任何其他跨服务器 DML 操作)引用包括任何下列数据类型
的列的另一 GBase 8s 实例的数据库中的表、视图或同义词,则查询失败并报
错。:

BLOB

CLOB

INDEXKEYARRAY

POINTER

RTNPARAMTYPES

SELFUNCARGS

IFX_LO_SPEC

IFX_LO_STAT

STAT

CLIENTBINVAL

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 864

用户定义的 OPAQUE 类型

复合的类型(命名的或未命名的 ROW、COLLECTION、LIST、
MULTISET 或 SET)

任何以上罗列的 opaque 或复合的数据类型的 DISTINCT。
跨服务器查询不可访问另一 GBase 8s 实例的数据库,除非两个服务器都在它们
的 DBSERVERNAME 或 DSERVERALIASES 配置参数中和在 sqlhosts 信息中
定义 TCP/IP 或 IPCSTR 连接。对两个参与的服务器都要支持相同的连接类型
(TCP/IP 抑或 IPCSTR)的要求也适用于 GBase 8s 实例之间的任何通信,即使
二者位于同一台计算机上。
Select 列表中的表达式
在选择列表中,您可使用任何基本类型的表达式(列、常量、内建的函数、聚集
函数和用户定义的例程)及其组合。在 表达式 中描述表达式类型。以下部分展
示在选择列表中的简单表达式的示例。
您可通过加、减、乘、除算术运算符将简单的数值表达式连接组合起来。然而,
如果您组合列表达式与聚集函数,则必须在 GROUP BY 子句中包括该列表达
式。(另请参阅 GROUP BY 与 Projection 子句之间的依赖。)
通常,您不可在选择列表中使用变量(例如,在 GBase 8s ESQL/C 应用程序中的
主变量)本身。然而,如果以算术运算符或连接运算符将它与变量相连接,则选
择列表中的变量是有效的。
在 FOREACH SELECT 语句中,当 FROM 子句中的表为远程表时,您不可使用
选择列表中的 SPL 变量本身或随同列名称使用。当 FROM 子句中的表为本地表
时,您可使用 SPL 变量自身,或随同选择列表中的常量使用。
在 GBase 8s 的分布式查询中,表达式中的值(以及表达式返回的值)是受限
的,如 跨服务器事务中的数据类型 所述。在同一 GBase 8s 实例的其他数据库
中将其返回值用作表达式的任何 UDR,必须定义在每一参与的数据库中。
在 Projection 子句中,布尔操作符 NOT 不是有效的。
选择列

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 865
列表达式是在 SELECT 语句中最常用的表达式。要获取列表达式的语法和使用的
完整描述,请参阅 列表达式。下列示例在 Projection 子句中使用列表达式:
SELECT orders.order_num, items.price FROM orders, items;
SELECT customer.customer_num ccnum, company FROM customer;
SELECT catalog_num, stock_num, cat_advert [1,15] FROM catalog;
SELECT lead_time - 2 UNITS DAY FROM manufact;
选择常量
如果您在 projection 列表中包含常量表达式,则对查询返回的每一行返回相同的
值(除了当常量表达式为 NEXTVAL 之外)。要了解常量表达式的语法和使用的完
整描述,请参阅 常量表达式。下列示例展示选择列表之内的常量表达式:
SELECT 'The first name is', fname FROM customer;
SELECT TODAY FROM cust_calls;
SELECT SITENAME FROM systables WHERE tabid = ;1
SELECT lead_time - 2 UNITS DAY FROM manufact;
SELECT customer_num + LENGTH('string') from customer;
选择内建的函数表达式
内建的函数表达式使用对查询中每一行求值的函数。所有内建的函数表达式都需
要参数。这些表达式包含时间函数和长度函数,当它们随同列名称作为参数使用
时。下列示例展示 Projection 子句的选择列表之内的内建的函数表达式:
SELECT EXTEND(res_dtime, YEAR TO SECOND) FROM cust_calls;
SELECT LENGTH(fname) + LENGTH(lname) FROM customer;
SELECT HEX(order_num) FROM orders;
SELECT MONTH(order_date) FROM orders;
选择聚集函数表达式
聚集函数返回对一系列被查询的行的一个值。此值依赖于 SELECT 语句指定的
WHERE 子句的行的集合。如果缺少 WHERE 子句,则聚集函数采用的值依赖于
FROM 子句构成的所有行。
下列示例展示 projection 列表中的聚集函数:
SELECT SUM(total_price) FROM items WHERE order_num = 1013;
SELECT COUNT(*) FROM orders WHERE order_num = 1001;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 866
SELECT MAX(LENGTH(fname) + LENGTH(lname)) FROM customer;
然而,如果 Projection 子句未指定 SELECT 语句的 DISTINCT 或 UNIQUE 关
键字,则查询可包括一个或多个包括 DISTINCT 或 UNIQUE 关键字作为参数列
表的第一个规范的聚集函数:
SELECT SUM(DISTINCT total_price) FROM items WHERE order_num = 1013;
SELECT COUNT(DISTINCT *) FROM orders WHERE order_num = 1001;
SELECT MAX(LENGTH(fname) + LENGTH(UNIQUE lname)) FROM customer;
然而,如果 Projection 子句和聚集函数表达式都在同一查询中指定 DISTINCT 或
UNIQUE 关键字,则数据库服务器发出错误。
对于包括聚集函数表达式的网格查询,您必须在子查询中指定 GRID 子句,每一
网格服务器计算的聚集表达式的值为商,这个商的分母在参与的网格服务器之间
不同。
请不要将 SQL 聚集函数与“联机分析处理”(OLAP)窗口聚集函数混淆,它们是
不同类别的函数。
当聚集函数表达式紧跟在 OVER 子句之后时,数据库服务器尝试将它解释为
OLAP 聚集函数。有些 OLAP 聚集函数与 SQL 聚集函数同名(并支持相同语法
的子集),但这两类函数的行为不同。
SQL 聚集函数可嵌套在 OLAP 聚集函数之中。例如,在 dollars 为 sales 表
中的列的上下文中,下列查询是有效的:
SELECT AVG(SUM(dollars)) OVER() FROM sales;
在上述示例中,SUM 函数是 SQL 聚集函数,且包含的 AVG 函数是 OLAP 窗
口函数。查询处理的顺序规定总是在分组和聚集操作之后、最后的 ORDER BY
操作之前计算 OLAP 函数。
选择 OLAP 窗口表达式
您可在 Projection 子句的选择列表中包括 OLAP 窗口表达式。
“联机分析处理”(OLAP)函数可返回对查询或子查询的整个结果集、对 OLAP
定义的符合条件的行的分区的子集的排名、行号和聚集函数信息。您可使用
OLAP 规范来定义对于数据的检测维度结果集的分区之内移动窗口,以及标识模
式、趋势和数据集内的例外。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 867
包括 OLAP 窗口表达式的查询返回该查询的结果集中的行,以及 OLAP 窗口函
数的结果,如果那些函数有任何返回的话。
OLAP 窗口聚集函数表达式可作为另一 OLAP 窗口聚集函数的参数。然而,
OLAP 窗口聚集不可为非分析的聚集函数的参数。
选择用户定义的函数表达式
用户定义的函数扩展了您可用的函数的范围,并允许您对您选择的每一行执行子
查询。
下列示例为每一 customer_num 调用 get_orders( ) 用户定义的函数,并显示
n_orders 标签之下的返回的值:
SELECT customer_num, lname, get_orders(customer_num) n_orders
FROM customer;
如果 SELECT 语句中的 SPL 例程包含某些 SQL 语句,则数据库服务器返回错
误。要获取关于在查询之内调用的 SPL 例程中不可使用哪些 SQL 语句的信息,
请参阅 在数据操纵语句中 SPL 例程的限制。
要获取用户定义的函数表达式的完整语法,请参阅 用户定义的函数。
选择使用算术运算符的表达式
您可将数值表达式与算术运算符组合来生成复合的表达式。您不可将包含聚集函
数的表达式与列表达式组合。这些示例展示在 Projection 子句中的选择列表之内
使用算术运算符的表达式:
SELECT stock_num, quantity*total_price FROM customer;
SELECT price*2 doubleprice FROM items;
SELECT count(*)+2 FROM customer;
SELECT count(*)+LENGTH('ab') FROM customer;
选择 ROW 字段
您可以 row.field 表示法来选择命名的或未命名的 ROW 类型列的特定字段。
例如,假设您有下列表结构:
CREATE ROW TYPE one (a INTEGER, b FLOAT);
CREATE ROW TYPE two (c one, d CHAR(10));
CREATE ROW TYPE three (e CHAR(10), f two);

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 868

CREATE TABLE new_tab OF TYPE two;
CREATE TABLE three_tab OF TYPE three;
下列示例展示在选择列表中为有效的表达式:
SELECT t.c FROM new_tab t;
SELECT f.c.a FROM three_tab;
SELECT f.d FROM three_tab;
您还可在字段名的位置输入星号(*)来表示被选择的 ROW 类型列的所有字
段。
例如,如果 my_tab 表有一包含四个字段的名为 rowcol 的 ROW 类型列,则下
列 SELECT 语句检索 rowcol 列的所有四个字段:
SELECT rowcol.* FROM my_tab;
您还可通过仅指定列名称来从 row 类型列检索所有字段。此示例与前一查询有相
同的作用:
SELECT rowcol FROM my_tab;
您不仅可随同 ROW 类型列使用 row.field 表示法,还可随同取值结果为 ROW
类型值的表达式使用。要获取更多信息,请参阅在“表达式”部分中的 列表达式。
声明显示标签
您可为 Projection 子句的选择列表中的任何列或列表达式声明显示标签。仅在
SELECT 语句正在执行时,此临时名称有效。
在 DB-Access 中,显示标签显示为 SELECT 语句的输出中那列的标题。
在 GBase 8s ESQL/C 中,display_label 的值保存在 sqlda 结构的 sqlname 字段
中。要获取更多关于 sqlda 结构的信息,请参阅 GBase 8s ESQL/C 程序员手册。
如果您的显示标签是 SQL 关键字,则请使用 AS 关键字来阐明语法。例如,要
使用 UNITS、YEAR、MONTH、DAY、HOUR、MINUTE、SECOND 或
FRACTION 作为显示标签,请随同该显示标签使用 AS 关键字。下列语句使用
随同 minute 的 AS 作为显示标签:
SELECT call_dtime AS minute FROM cust_calls;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 869
要了解 SQL 的关键字,请参阅 GBase 8s 的 SQL 关键字。
如果您使用 INTO Table 子句来创建临时的或永久的表来存储查询结果,则必须
为不是简单类表达式的在选择列表中的任何数据库对象或表达式声明显示标签。
在临时的或永久的表中,显示标签用作列的名称。
如果您正在使用 SELECT 语句来定义视图,请不要使用显示标签。而要在
CREATE VIEW 列列表中指定想要的标签名称。
声明列别名
您可为 Projection 子句的选择列表中的任何列声明别名。GROUP BY 子句可通过
列的别名引用它。仅在 SELECT 语句正在执行时,此临时名称才有效。
如果您的别名是 SELECT 语句的 SQL 关键字,则请使用 AS column_alias 关键
字来阐明语法。例如,要使用 FROM 作为表别名,必须在该别名前紧接着 AS 关
键字,来避免语法错误。下列语句使用带有以 from 的 AS 作为别名:
SELECT status AS from FROM stock GROUP BY from;
下列等同的查询声明 pcol 作为别名,并在 GROUP BY 子句中使用那个别名:
SELECT pseudo_corinthian AS pcol FROM architecture GROUP BY pcol;
SELECTt pseudo_corinthian pcol FROM architecture GROUP BY pco1;
INTO 子句
在 SPL 例程或 GBase 8s ESQL/C 程序中使用 INTO 子句来指定程序变量或主变
量来接收 SELECT 检索的数据。
INTO 子句


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 870
元素
描述
限制
语法
data_structure
声明了作为主变量的
结构
必须能够存储正在
选择的值的元素的
数据类型
特定于语言
indicator_var
如果相应的
output_var 收到
NULL 值,则来接收返
回代码的程序变量
可选的;如果相应
的 output_var 的
值由为 NULL 的可
能性,则使用指示
符变量
特定于语言
output_var
接收相应的选择列表
项的值的程序或主变
量。可为集合变量
接收变量的顺序必
须与 Projection
子句的选择列表中
相应的项的顺序相
匹配
特定于语言
INTO 子句指定一个或多个接收查询返回的值的变量。如果它返回多个值,则以
您指定这些变量的顺序将它们赋予变量列表。
如果 SELECT 语句是孤立的(即,不是 DECLARE 语句的一部分,且不使用
INTO 子句),则必须为单 SELECT 语句。单 SELECT 语句仅返回一行。
接收的变量的数目必须等于 Projection 子句的选择列表中项的数目。每一接收的
变量的数据类型应与选择列表中相应的列或表达式的数据类型相兼容。
当接收的变量的数据类型与被选择的项不相匹配时,要了解数据库服务器采取的
活动,请参阅 ESQL/C 中的警告。
下列示例展示 GBase 8s ESQL/C 中的单 SELECT 语句:
EXEC SQL select fname, lname, company
into :p_fname, :p_lname, :p_coname
from customer where customer_num = 101;
在 SPL 例程中,如果 SELECT 返回多于一行,则您必须使用 FOREACH 语句
来分别地访问这些行。SELECT 语句的 INTO 子句持有获取的值。要获取更多信
息,请参阅 FOREACH。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 871
带有指示符变量的 INTO 子句
如果存在从查询返回的数据值为 NULL 的可能性,则请在 INTO 子句中使用
ESQL/C 指示符变量。要获取更多信息,请参阅 GBase 8s ESQL/C 程序员手册。
带有游标的 INTO 子句
如果 SELECT 语句返回多于一行,则您必须在 FETCH 语句中使用游标来分别
地存取这些行。您可将 INTO 子句放在 FETCH 语句中,而不是在 SELECT 语
句中,但您不应将其同时放在两个语句中。
下列 GBase 8s ESQL/C 代码示例展示您可使用 INTO 子句的不同的方式。如两
个示例所示,您必须首先使用 DECLARE 语句来声明游标。
在 SELECT 语句中使用 INTO 子句
EXEC SQL declare q_curs cursor for
select lname, company
into :p_lname, :p_company
from customer;
EXEC SQL open q_curs;
while (SQLCODE == 0)
EXEC SQL fetch q_curs;
EXEC SQL close q_curs;
使用 FETCH 语句中的 INTO 子句
EXEC SQL declare q_curs cursor for
select lname, company from customer;
EXEC SQL open q_curs;
while (SQLCODE == 0)
EXEC SQL fetch q_curs into :p_lname, :p_company;
EXEC SQL close q_curs;
准备 SELECT ... INTO 查询
在 GBase 8s ESQL/C 中,您不可准备带有 INTO 子句的查询。您可准备不带有
INTO 子句的查询,为准备好的查询声明游标,打开游标,然后使用带有 INTO
子句的 FETCH 语句来获取程序变量之内的游标。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 872
或者,您可为查询声明游标,而不准备该查询,并当您声明该游标时在该查询中
包括 INTO 子句。然后打开该游标并获取该游标,而不使用 FETCH 语句的
INTO 子句。
使用带有 INTO 子句的数组变量
在 GBase 8s ESQL/C 中,如果您随同包含 INTO 子句的 SELECT 语句使用
DECLARE 语句,且该变量为数组元素,则可以整数字面值或变量来标识该数组
的单个元素。当声明该游标时,确定用作下标的变量的值;随后该下标变量表现
为常量。
下列 GBase 8s ESQL/C 代码示例为 SELECT ... INTO 语句声明游标,使用变量
i 和 j 作为数组 a 的下标。在您声明该游标之后,SELECT 语句的 INTO 子句等
同于 INTO a[5], a[2]。
i = 5
j = 2
EXEC SQL declare c cursor for
select order_num, po_num into :a[i], :a[j] from orders
where order_num =1005 and po_num =2865;
您还可在 FETCH 语句中使用程序变量来指定 INTO 子句中程序的元素。在每一
获取操作时为程序变量求值,而不是当您声明该游标时求值。
错误检查
如果收到的变量的数据类型与被选择的项的数据类型不相匹配,如果可能,则将
被选择的项的数据类型转换为该变量的数据类型。如果不可能转换,则发生错
误,并在 status 变量、sqlca.sqlcode 或 SQLCODE 中返回负数。在此情况下,
程序变量中的值是无法预知的。
在符合 ANSI 的数据库中,如果罗列在 INTO 子句中的变量的数目不同于
Projection 子句的选择列表中项的数目,则会收到错误。
ESQL/C 中的警告
在 GBase 8s ESQL/C 中,如果罗列在 INTO 子句中的变量的数目不同于
Projection 子句中项的数目,则在 sqlwarn 结构中返回警告:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 873
sqlca.sqlwarn.sqlwarn3。转换的变量的实际数目少于这两个数目。要获取更多关
于 sqlwarn 结构的信息,请参阅 GBase 8s ESQL/C 程序员手册。
FROM 子句
SELECT 语句的 FROM 子句罗列要从其检索数据的表对象。
FROM 子句有此语法:
FROM 子句

表引用

关系

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 874

元素
描述
限制
语法
alias
在此查询中的表、
视图或派生的表的
临时名称
请参阅 AS 关键字。
标识符
derived
_column
在表表达式中派生
的列的临时名称
除非底层集合为 ROW
类型,否则您声明的
derived_column 名称
不能超过一个
标识符
external
从其检索数据的外
部的表
必须存在,但不可为外
连接中的外表
数据库对象名
synonym、
table、
view
从其检索数据的表
的同义词
同义词和表或它指向的
视图必须存在
数据库对象名
每个 SELECT 语句都需要 FROM 子句,不论是否需要任何数据源。如果您的查
询使用数据库服务器来对一不需要数据源的表达式求值,则 FROM 子句可引用
您在其上持有充足的访问权限的当前数据库中任何现有的表,如下例所示:
SELECT ATANH(SQRT(POW(4,2) + POW(5,2))) FROM systables;
如果 FROM 子句指定多个数据源,则该查询称为连接,因为它的结果集可从几
个表引用连接行。要了解更多关于连接的信息,请参阅 连接表的查询。
表或视图的别名
您可为 FROM 子句中的表或视图声明别名。如果你这么做,则必须在 SELECT
语句的其他子句中使用该别名来引用该表或视图。您还可使用别名来缩短查询。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 875
下列示例展示 FROM 子句的典型使用。第一个查询从 customer 表选择所有列和
行。第二个查询在 customer 和 orders 表之间使用连接,来选择所有已下了订
单的客户。
SELECT * FROM customer;
SELECT fname, lname, order_num FROM customer, orders
WHERE customer.customer_num = orders.customer_num;
下一示例等同于前一示例中的第二个查询,但它在 FROM 子句中声明别名,并
在 WHERE 子句中使用它们:
SELECT fname, lname, order_num FROM customer c, orders o
WHERE c.customer_num = o.customer_num;
别名(有时称为相关名称)对自连接特别有用。要获取更多关于自连接的信息,
请参阅 自连接。在自连接中,您必须在 FROM 子句中罗列表名称两次,并为该
表名称的两个示例各自声明一个不同的别名。
AS 关键字
如果您使用可能发生歧义的此作为别名(或作为显示标签),则必须以关键字
AS 开始它的声明。如果您使用任何关键字 ORDER、FOR、AT、GROUP、
HAVING、INTO、NOT、UNION、WHERE、WITH、CREATE 或 GRANT 作为
表或视图的别名,则需要此关键字。
如果下一示例未包括了 AS 关键字来表明 not 是显示标签,而不是操作符,则数
据库服务器会发出错误:
CREATE TABLE t1(a INT);
SELECT a AS not FROM t1;
如果您未为集合派生的表声明别名,则数据库服务器为它指定一个与实现相关的
名称。
表表达式
表表达式(有时称为派生的表)是表或视图的名称,或对一系列行求值的规范。
这些行通常是嵌入到嵌套的 SELECT 语句中,或一些其他 SQL 语句中的查询的
结果。
表表达式可有下列语法:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 876
表表达式

元素
描述
限制
语法
subquery 外查询可用其结果的
嵌套的查询
请参阅下文用法说明
SELECT 语句
table
_object
名称、同义词,或
表、视图或
EXTERNAL 表的别名
必须存在,或必须引用
SELECT 语句创建的派
生的表
标识符 或 数据
库对象名
用法
表表达式可为简单的或复合的:

简单的表表达式
简单的表表达式是在保持查询结果的正确性时,其基础查询可包含进主查
询内的表达式。

复合的表表达式
复合的表表达式是在保持查询结果的正确性时,其基础查询不可包含进主
查询内的表达式。数据库服务器将这样的表表达式具体化成在主查询中使
用的临时表。在 FROM 子句中指定聚集、集合操作符或 ORDER BY 子
句的子查询作为复合的表表达式实现,通常需要比简单的表表达式更多的
数据库服务器资源。
在两种情况下,该表表达式作为常规的 SQL 查询求值,且它的结果可被认为是
逻辑表。此逻辑表及其列可就如普通的基础表那样使用,但它不是持久的。它仅
在引用它的查询的执行期间存在。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 877
对表表达式的限制
表表达式与常规的 SELECT 语句有相同的语法,但有在其他上下文中适用于子查
询的大部分限制。表表达式不可包括显式地创建结果表的 SELECT INTO 子句。
GBase 8s 不支持“通用化的键”索引。它支持在 CREATE TRIGGER 语句的触发器
活动中的表表达式,并作为 Select 触发器的触发事件。 GBase 8s 还支持表表达
式中的 ORDER BY 子句。
GBase 8s 支持迭代器函数作为 FROM 子句表标识符。然而,SPL 的 CALL 语
句不可在 FROM 子句中的子查询内调用迭代器 TABLE 函数。
除了这些限制之外,任何有效的 SQL 查询都可为表表达式。表表达式可嵌套在
另一表表达式之内,且可在它的定义中包括表和视图。您可在 CREATE VIEW 语
句中使用表表达式来定义视图。
相关的子查询和派生的表
相关的子查询是引用未罗列在其 FROM 子句中的表的列的子查询。相反,仅引
用罗列在其 FROM 子句中的表中的列的子查询是不相关的子查询。
在下列示例中,在其 FROM 子句中定义派生的表的不相关的子查询,在其 WHERE
子句中包含相关的子查询:
SELECT * FROM (SELECT * FROM t1
WHERE a IN (SELECT b FROM t2 WHERE t1.a = t2.b));
此处,在第一个 WHERE 子句中的子查询是相关的子查询,因为它引用表 t1 的
列 a,但它的 FROM 子句仅指定表 t2。
在 FROM 子句表表达式中,GBase 8s 还支持 ORDER BY 子句,这在 FROM
子句之外的子查询中不是有效的。在表表达式中通过 ORDER BY 子句指定的列
或表达式不需要包括在 Projection 子句中。
横向的派生的表
在定义派生的表的 FORM 子句中的任何查询都必须紧跟在 LATERAL 关键字之
后,如果那个查询引用任何其他表或列,在同一 FROM 子句中该表或列出现得
早于定义该派生的表的那个查询的话。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 878
横向的派生的表,以及可在它们的语法中声明的表和列别名的引用的范围,是
SQL 语言的 ISO/ANSI 标准的一部分。此为 FROM 子句中横向的派生的表的语
法:
LATERAL 派生的表

元素
描述
限制
语法
alias
在此为 subquery 结
果的派生的表声明的
临时名称
请参阅 AS 关键
字。
标识符
column_alias 在此为派生的表中列
声明的临时的名称

标识符
subquery
指定要检索的行
可为不相关的或相
关的
SELECT 语句
用法
如果其结果集为派生的表的 subquery 引用任何早于在同一 FROM 子句中出现的
任何表或列,则需要 LATERAL 关键字。此处,早于意味着在 FROM 子句中的
从左至右的语法令牌顺序中“在派生的表的左边”。以 LATERAL 关键字定义的派
生的表称为横向的派生的表。
这支持对 FROM 子句中的其他表中列的引用,而不是仅对随后的派生的表中列
的引用。可提升在连接一个或多个派生的表的 SELECT 语句中的性能。在
DELETE、UPDATE 和 CREATE VIEW 语句之内的派生的表中,横向的表和列
引用也是有效的。
如果在派生的表中,已解析了所有不相关的表和列引用,则在这些派生的表的
FROM 子句中不需要 LATERAL 关键字。
横向的派生的表的示例

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 879
下列查询在 FROM 子句中包括横向的派生的表,其中 t1_a 是横向的相关引用:
SELECT * FROM t1 ,
LATERAL (SELECT t2.a AS t2_a
FROM t2 WHERE t2.a = t1.a);
在下一示例中,d.deptno 是横向的相关引用:
SELECT d.deptno, d.deptname,
empinfo.avgsal, empinfo.empcount
FROM department d,
LATERAL (SELECT AVG(e.salary) AS avgsal,
COUNT(*) AS empcount
FROM employee e
WHERE e.workdept=d.deptno) AS empinfo;
在此,列表达式的 avgsal 和 empcount 别名以及 empinfo 横向的表引用出现在
外查询的 projection 列表中,使用关联 deptno,从 department 表和派生的表连
接符合条件的行。
对横向相关的引用的限制
下列限制适用于横向的关联的表和列引用:

不可在 ANSI FULL OUTER JOIN 查询中使用它们。

不可在 ANSI RIGHT OUTER JOIN 查询中使用它们。

不可在 GBase 8s 扩展 OUTER JOIN 查询中使用它们。
可用性和性能考虑
虽然通过视图、子查询可实现与表表达式等同的功能,但表表达式简化查询的公
式,使得语法更加灵活和直观,并支持 SQL 的 ANSI/ISO 标准。
查询优化器不具体化 FROM 子句指定的简单的表表达式。与使用 GBase 8s 扩展
TABLE (MULTISET ( SELECT ... )) 语法来在 FROM 子句中指定等同的派生的表
的查询的性能比起来,在 FROM 子句中对表表达式使用 ANSI/ISO 语法的查询
的性能至少一样好,设置如 UNION、INTERSECT 或 MINUS 操作符 这样的操
作符,或将 ORDER BY 规范作为复合的表表达式实现,可造成比简单的表表达
式更大的开销。请使用 SET EXPLAIN 语句来检测查询计划和表表达式的预计成
本。
下列是有效的表表达式的示例:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 880
SELECT * FROM (SELECT * FROM t);

SELECT * FROM (SELECT * FROM t) AS s;

SELECT * FROM (SELECT * FROM t) AS s WHERE t.a = s.b;

SELECT * FROM (SELECT * FROM t) AS s, (SELECT * FROM u) AS v WHERE
s.a = v.b;

SELECT * FROM (SELECT SKIP 2 col1 FROM tab1 WHERE col1 > 50 ORDER
BY col1 DESC);

SELECT * FROM (SELECT col1,col3 FROM tab1
WHERE col1 < 50 GROUP BY col1,col3 ORDER BY col3 ) vtab(vcol0,vcol1);

SELECT * FROM (SELECT * FROM t WHERE t.a = 1) AS s,
OUTER
(SELECT * FROM u WHERE u.b = 2 GROUP BY 1) AS v WHERE s.a = v.b;

SELECT * FROM (SELECT a AS colA FROM t WHERE t.a = 1) AS s,
OUTER
(SELECT b AS colB FROM u WHERE u.b = 2 GROUP BY 1) AS v
WHERE s.colA = v.colB;

CREATE VIEW vu AS SELECT * FROM (SELECT * FROM t);

SELECT * FROM ((SELECT * FROM t) AS r) AS s;

对连接和子查询中的外部表的限制
当您使用在连接和子查询中的外部表时,受到下列限制:

在查询中只有一个外部表是有效的。

该外部表不可为外连接中的外表。

对于不可转换成连接的子查询,您可使用在主查询中的外部表,但不可使
用子查询中的。

您不可对外部表进行自连接。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 881
要获取更多关于子查询的信息,请参阅您的 GBase 8s 性能指南 。
LIMIT 子句
LIMIT 子句顺序获取结果集中某条记录开始的前 N 条记录。
语法


元素
描述
限制
语法
M
返回的行数或结果集中的行计数 大于等于 0 的正整数 精确数值
N
返回的行数或结果集中的行计数 大于等于 0 的正整数 精确数值
注:M,N 元素含义随 LIMIT 子句的使用方式不同而不同。
用法
具有以下三种方式:

LIMIT N :指定取得结果集中前 N 条记录。

LIMIT M,N :指定取得结果集中第 M 条记录之后的 N 条记录。

LIMIT M OFFSET N :指定取得结果集中第 N 条记录之后的 M 条记
录。
注意:LIMIT 不能与 TOP 同时出现在查询语句中。
例如,查询前 2 条记录:
SELECT emp_id, name FROM employee LIMIT 2;
查询第 3、4 条记录:
SELECT emp_id, name FROM employee LIMIT 2 OFFSET 2;
查询第 5、6、7 条记录:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 882
SELECT emp_id, name FROM employee LIMIT 4,3;
以下查询返回符合员工编号(emp_id)大于 2 条件结果集中的第 3、4、5 条记
录:
SELECT emp_id, name FROM employee where emp_id >’2’LIMIT 3 OFFSET
2;
ONLY 关键字
如果 FROM 子句包括在类型表层级之内为超级表的永久表,则该查询从超级表
及其缺省情况下的子表都返回符合条件的行,除非您指定 ONLY 关键字。
仅对于从超级表返回行的 SELECT 语句,您必须在 FROM 子句中包括 ONLY 关键
字,紧排在超级表名称之前,且您必须将超级表的标识符或同义词括在小括号之
内,如此例所示:
SELECT * FROM ONLY(super_tab);
此查询的数据源不包括 super_tab 的子表。
从集合变量选择
与“集合派生的表”段结合的 SELECT 语句允许您从集合变量选择元素。
“集合派生的表”段标识从其选择元素的集合变量。(请参阅 集合派生表。)
使用带有 SELECT 的集合变量
要修改集合数据类型的列的内容,您可以各种方式使用带有集合变量的 SELECT
语句:

您可将集合列的内容(如果有的话)选择到集合变量之内。
您可将列的数据类型指定为类型 COLLECTION 的集合变量(即,非类型
集合变量)。

您可从集合变量选择内容来决定您可能想要更新的数据。

您可从集合变量选择内容 INTO 另一变量,以便更新确定的集合元素。
INTO 子句为从集合变量选择的元素值标识变量。在 INTO 子句中的主变
量的数据类型必须与相应的集合元素的数据类型相兼容。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 883

您可使用 Collection 游标来从 GBase 8s ESQL/C 集合变量选择一个或多
个元素。
要获取更多包括对 SELECT 语句的限制的信息,请参阅 将游标与准备好
的语句相关联。

您可使用 Collection 游标来从 SPL 集合变量选择一个或多个元素。
要获取更多包括对 SELECT 语句的限制的信息,请参阅 使用 SELECT ...
INTO 语句。
当要连接的表之一是集合时,FROM 子句不可指定连接。当该集合变量拥有您的
集合派生的表时,此限制有效。另请参阅 集合派生表,以及在本章中的
INSERT、UPDATE 和 DELETE 语句描述。
从 Row 变量(ESQL/C)选择
SELECT 语句可包括“集合派生的表”段来从 row 变量选择一个或多个字段。
“集合派生的表”段标识要从其选择字段标识 row 变量。要获取更多信息,请参阅
集合派生表。
要选择字段:
1. 在您的 GBase 8s ESQL/C 程序中创建 row 变量。
2. 可选地,以字段值填充 row 变量。
您可以 SELECT 语句(无“集合派生的表”段)将 ROW 类型列创建到
row 变量内。或者,您可以 UPDATE 语句和“集合派生的表”段将字段值
插入到 row 变量之内。
3. 以 SELECT 语句和“集合派生的表”段从 row 变量选择行字段。
4. 一旦 row 变量包含正确的字段值,您可在表或视图名称上使用 INSERT
或 UPDATE 语句来将 row 变量的内容保存在命名的或未命名的行列
中。
INTO 子句可指定主变量来把保持从 row 变量选择的字段值。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 884
主变量的类型必须与字段的类型相兼容。例如,此代码片断将 width 字段值放到
rect_width 主变量之内。
EXEC SQL BEGIN DECLARE SECTION;
ROW (x INT, y INT, length FLOAT, width FLOAT) myrect;
double rect_width;
EXEC SQL END DECLARE SECTION;
...
EXEC SQL SELECT rect INTO :myrect FROM rectangles
WHERE area = 200;
EXEC SQL SELECT width INTO :rect_width FROM table(:myrect);
对 row 变量的 SELECT 语句有下列限制:

在 Projection 子句的选择列表中不允许有表达式。

ROW 列不可在 WHERE 子句比较条件中。

如果 row 类型包含 opaque、distinct 或内建的数据类型,则 Projection
子句必须为星号(*)。

罗列在 Projection 子句中的列必须仅有未限定的名称。它们不可使用语
法 database@server:table.column。

不允许有下列子句:GROUP BY、HAVING、INTO TEMP、ORDER BY
和 WHERE。

FROM 子句对进行连接没有任何规定。
您可以 UPDATA 语句的“集合派生的表”段修改 row 变量。(INSERT 和
DELETE 语句不支持“集合派生的表”段中的 row 变量。)
row 变量存储行的字段。然而,它与数据库行没有内在的连接。一旦 row 变量包
含正确的字段值,那么您必须以下列 SQL 语句之一将该变量保存到 ROW 列之
内:

要以 row 变量来更新表中的 ROW 列,请对表或视图名称使用
UPDATE 语句,并在 SET 子句中指定 row 变量。要获取更多信息,请
参阅 更新 ROW 类型列。

要将行插入到 ROW 列,请对表或视图使用 INSERT 语句并在
VALUES 子句中指定 row 变量。请参阅 将值插入到 ROW 类型列内。
要获取如何使用 SPL row 变量的示例,请参阅 GBase 8s SQL 教程指南。要获取
关于使用 GBase 8s ESQL/C row 变量的信息,请参阅在 GBase 8s ESQL/C 程序
员手册 中对复合的数据类型的讨论。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 885
迭代器函数
FROM 子句可包括对迭代器函数的调用,来为查询指定来源。迭代器函数是用户
定义的功能,多次返回到它的调用 SQL 语句,每次返回至少一个值。
您可使用虚拟的表接口查询迭代器 UDR 的返回结果集。使用此语法来在 FROM 子
句中调用迭代器函数:
迭代器

元素
描述
限制
语法
column
在此为 table 中的虚
拟列声明的名称
在 table 中的 column 名
称之中必须是唯一的,且
不可包括限定符。
标识符
iterator 迭代器函数的名称
必须注册在该数据库中
标识符
table
在此为持有 iterator
结果集的虚拟表声明的
名称
不可包括限定符
标识符
在早于 GBase 8s 10.5 的版本中,要求有关键字 FUNCTION(或
PROCEDURE)。在此版本中,这些对 SQL 的 ANSI/ISO 标准的关键字扩展是
可选的,且无效。下列两个指定 fibGen( ) 作为迭代器函数的查询规范,是等同
的:
SELECT * FROM TABLE FUNCTION ( fibGen(10));
SELECT * FROM TABLE ( fibGen(10));
仅可在此查询的上下文之内引用 table。在 SELECT 语句终止之后,虚拟表不再
存在。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 886
列的数目必须与通过迭代器返回的值的数量相匹配。外部的函数可返回不超过一
个值(但那可为集合数据类型)。SPL 例程可返回多个值。
然而,如果迭代器 table 函数的任何参数是聚集表达式,则数据库服务器发出错
误 -595.
例如,要引用该 SELECT 语句的其他部分中的虚拟 table,在 WHERE 子句或
HAVING 子句中,您必须在 FROM 子句中声明它的名称和虚拟的列名称。如果您在
Projection 子句的 Select 列表中使用星号标记,则无需在 FROM 子句中声明
table 名称或 column 名称:
SELECT * FROM ...
要获取在查询中使用迭代器函数的更多信息和示例,请参阅 GBase 8s 用户定义
的例程和数据类型开发者指南 。
连接表的查询
如果 FROM 子句指定多个表引用,则该查询可从几个表或视图连接行。
连接条件指定来自要被连接的每一表的至少一列之间的关系。由于要对连接条件
中的列进行比较,因此它们必须有可兼容的数据类型。
注: 在缺省情况下,数据库服务器连接表和视图所依的顺序不依赖于它们在
FROM 子句中被引用的顺序。要强制被连接的表的顺序与 FROM 子句顺序相匹配,
则您可在 SELECT 关键字之后指定 ORDERED 优化器伪指令。要获取更多信息,请
参阅 连接顺序伪指令 部分。
SELECT 语句的 FROM 子句可指定几种连接类型。
FROM 子句关键字
相应的结果集
CROSS JOIN
笛卡尔积(所有可能的行的对)
INNER JOIN
仅来自满足连接条件的 CROSS 的行
LEFT OUTER JOIN
一表的满足条件的行,和另一表的所有行
RIGHT OUTER JOIN
与 LEFT 相同,但两表的角色互换

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 887
FULL OUTER JOIN
来自两表的 INNER 连接的所有行的并集,以及在其
他表中没有匹配的每一表的所有行(在其他的表的
被选择的行中使用 NULL 值)
在关系模型的文献中最后四个类别统称为“连接类型”;CROSS JOIN 忽略在被连
接的表中特定的数据值,返回笛卡尔积作为它的结果集:每个可能的行的对,其
中,每一对中的一行来自每一表。
在内(或简单的)连接中,结果仅包含满足连接条件的行的组合。外连接保留可
能会被内连接废弃的那些行。在外连接中,结果包含满足连接条件的行的组合以
及来自主表的可能会被废弃的那些行。在来自从表选择的列中,来自主表但在从
表中没有相匹配的行的那些行包含 NULL 值。
GBase 8s 对于左外连接支持两种不同的语法:

GBase 8s 扩展 OUTER 连接语法

符合 ANSI 的语法
对于外连接,数据库服务器的较早版本仅支持 GBase 8s 扩展语法。 GBase 8s 继
续支持这种传统语法,但在 SQL 语言中对于连接查询使用符合 ISO/ANSI 标准
的语法,提供更大的灵活性。然而,在视图定义中, GBase 8s 扩展语法不要求
具体化的视图,因此它可能导致性能劣势。
如果您使用符合 ANSI 的语法来指定 FROM 子句中的连接,则对于同一查询块中
的所有外连接,还必须使用符合 ANSI 的语法。因此,您不可仅以 OUTER 关键字
开启另一外连接。例如,下列查询不是有效的:
SELECT * FROM customer, OUTER orders RIGHT JOIN cust_calls
ON (customer.customer_num = orders.customer_num)
WHERE customer.customer_num = 104);
这会返回错误,因为它尝试对外连接将 GBase 8s 扩展 OUTER 语法与符合
ANSI 的 RIGHT JOIN 语法组合在一起。
要了解 GBase 8s 扩展对 LEFT OUTER 外连接的语法,请参阅 GBase 8s 扩展外
连接 部分。
符合 ANSI 的连接
对于连接的符合 ANSI 的语法支持这些连接规范:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 888

要使用 CROSS 连接、LEFT OUTER、RIGHT OUTER 或 FULL OUTER
连接,或 INNER(或简单的)连接,请参阅 ANSI INNER 连接。

要使用前连接过滤器,请参阅 使用 ON 子句。

要在 WEHERE 子句中使用一个或多个后连接过滤器,请参阅 指定后连
接过滤器。

要使得外连接的主或从部分成为另一连接的结果集,请参阅 使用连接作
为外连接的主部分或从部分。
重要: 当您在 GBase 8s 中创建新的查询时,请对连接使用符合 ANSI 的语法。
ANSI 表引用
此图展示对表引用的符合 ANSI 的语法。
ANSI 表引用

元素
描述
限制
语法
alias
在 SELECT 的作用域之内
表或视图的临时名称
请参阅 AS 关键字。
标识符
synonym、
table、
view
从其检索数据的源
它指向的同义词和表或视
图必须存在
数据库对
象名
在此,ONLY 关键字的语义与在 GBase 8s 扩展“表引用”段的语义相同,如在
ONLY 关键字 中描述的那样。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 889
当您为表引用声明别名(也称为关联名称)时,AS 关键字是可选的,如在 AS
关键字 中描述的那样,除非该别名与 SQL 关键字冲突。
ANSI 连接的表
对连接表使用符合 ISO/ANSI 的语法,您可指定 INNER JOIN、CROSS JOIN、
NATURAL JOIN、LEFT JOIN(或 LEFT OUTER JOIN)、RIGHT JOIN(或
RIGHT OUTER JOIN)和 FULL JOIN(FULL OUTER JOIN)关键字。在符合
ANSI 的外连接中,OUTER 关键字是可选的。
这是对于指定的内连接和外连接的符合 ANSI 的语法。
ANSI 连接的表

Join 选项

ON 子句

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 890

元素
描述
限制
语法
subquery 嵌入的查询 不可包含 FIRST 或 ORDER BY 子句 SELECT 语句
在同一查询块中,对于所有外连接您必须使用相同的连接语法形式(或 GBase 8s
扩展,或符合 ANSI)。当您使用符合 ANSI 的连接语法时,您还必须在 ON 子
句中指定连接条件。
如果“ANSI 连接的表”段紧跟在另一连接规范之后,则必须将它括在圆括号之
间。 例如,下列两个查询的第一个返回错误;第二个查询是有效的:
SELECT * FROM (T1 LEFT JOIN T2) CROSS JOIN T3 ON (T1.c1 = T2.c5)
WHERE (T1.c1 < 100); -- Ambiguous order of operations;

SELECT * FROM (T1 LEFT JOIN T2 ON (T1.c1 = T2.c5)) CROSS JOIN T3
WHERE (T1.c1 < 100); -- Unambiguous order of operations;
下列有效的查询指定外部 SELECT 语句的 FROM 子句之内的表表达式的嵌套的
LEFT OUTER 连接:
SELECT * FROM
( (SELECT C1,C2 FROM T3) AS VT3(V31,V32)
LEFT OUTER JOIN

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 891
( (SELECT C1,C2 FROM T1) AS VT1(VC1,VC2)
LEFT OUTER JOIN
(SELECT C1,C2 FROM T2) AS VT2(VC3,VC4)
ON VT1.VC1 = VT2.VC3)
ON VT3.V31 = VT2.VC3);
ANSI CROSS 连接
CROSS 关键字指定笛卡尔积,返回包括从每一被连接的表的一行的所有可能的成
对组合。
ANSI INNER 连接
要使用符合 ANSI 的语法创建内(或简单的)连接,请以 JOIN 或 INNER JOIN
关键字指定该连接。如果您仅指定 JOIN 关键字,则数据库服务器缺省地创建隐
式的内连接。内连接返回有一个或多个在其他一个表(或多个表)中的相匹配的
行的表中的所有行。废弃不相匹配的行。
ANSI LEFT OUTER 连接
LEFT 关键字指定将第一个表引用处理作为该连接中的主表的连接。在左外连接
中,外连接的从部分出现在起始该外连接规范的关键字的右边。结果集包括
INNER 连接返回的所有行,加上可能已从从表废弃的所有行。
ANSI RIGHT OUTER 连接
RIGHT 关键字指定连接,该连接处理第二个表引用作为连接中的从表。在右外连
接中,外连接的从部分出现在起始该外连接规范的关键字的左边。结果集包括
INNER 连接返回的所有的行,加上可能已从从表废弃了的所有行。
对横向派生的表的相关联引用不是 ANSI RIGHT OUTER 连接中有效的表引用。
例如,下列查询失败,因为在派生的表的 ON 子句中的相关联的引用 t1.c1 是不
受支持的横向相关联:
SELECT * FROM t1 RIGHT JOIN LATERAL
(SELECT * FROM t2 JOIN t3
ON t2.c1 = t1.c1) AS X ON 1=1;
ANSI FULL OUTER 连接

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 892
FULL 关键字指定连接,在该连接的结果集中包括其连接条件为真的笛卡尔积的
所有行,加上来自与连接条件不匹配的每一表的所有行。
在符合 ANSI 的连接中,该连接在 FROM 子句中指定 LEFT、RIGHT 或 FULL
关键字,OUTER 关键字是可选的。
对横向的派生表的相关联引用不是 ANSI FULL OUTER 连接中有效的表引用。例
如,下列查询失败,因为在派生的表的 ON 子句中的相关联引用 t1.c1 是不受支
持的横向的相关联:
SELECT * FROM t1 FULL JOIN LATERAL
(SELECT * FROM t2 JOIN t3
ON t2.c1 = t1.c1) AS X ON 1=1;
忽略您为符合 ANSI 的连接的查询指定的连接模式优化程序伪指令,但将伪指令
罗列在解释输出文件中的 Directives Not Followed 之下。
使用 ON 子句
使用 ON 子句来指定连接条件和任何表达式作为可选的连接过滤器。
下列来自 stores_demo 数据库的示例展示在 ON 子句中的连接条件如何组合
customer 与 orders 表:
SELECT c.customer_num, c.company, c.phone, o.order_date
FROM customer c LEFT JOIN orders o
ON c.customer_num = o.customer_num;
下表展示连接了的 customer 与 orders 表的一部分。
customer_num
company
phone
order_date
101
All Sports Supplies
408-789-8075
05/21/2008
102
Sports Spot
415-822-1289
NULL
103
Phil’s Sports
415-328-4543
NULL
104
Play Ball!
415-368-1100
05/20/2008





GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 893
在外连接中,您在 ON 子句中指定的连接过滤器(表达式)决定将从表的哪些行
连接到主(或外)表。根据定义,主表返回在连接了的表中的所有行。即,在
ON 子句中的连接过滤器对主表不起作用。
如果 ON 子句在主表上指定连接过滤器,则数据库服务器仅将那些满足连接过滤
器条件的主表行连接到从表中的行。连接的结果包含来自主表的所有行。那些不
满足连接过滤器条件的主表中的行,为从列以 NULL 值扩展。
下列来自 stores_demo 数据库的示例展示 ON 子句中连接过滤器的作用:
SELECT c.customer_num, c.company, c.phone, o.order_date
FROM customer c LEFT JOIN orders o
ON c.customer_num = o.customer_num
AND c.company <> "All Sports Supplies";
包含 All Sports Supplies 的行保留在连接的结果中。
customer_num
company
phone
order_date
101
All Sports Supplies
408-789-8075
NULL
102
Sports Spot
415-822-1289
NULL
103
Phil’s Sports
415-328-4543
NULL
104
Play Ball!
415-368-1100
05/20/2008




在 orders 表中,即使客户编号 101 的订单日期是 05/21/2008,放置连接过滤器
(c.company <> "All Sports Supplies")的作用是阻止在主表
customer 中的此行被连接到从表 orders。相反,order_date 的 NULL 值会扩展
到 All Sports Supplies 的行。
将连接过滤器应用到外连接的从部分中的基础表,可提升性能。要获取更多信
息,请参阅您的 GBase 8s 性能指南 。
指定后连接过滤器
当您使用 ON 子句来指定连接时,您可使用 WHERE 子句作为后连接过滤器。
数据库服务器将 WHERE 子句的后连接过滤器应用到外连接的结果。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 894
下列示例展示后连接过滤器的使用。此查询从 stores_demo 数据库返回数据。假
设您想要确定目录中的哪些项没有被订购。下一查询从 catalog 与 items 表创
建该数据的外连接,然后从特定的制造商(HRO)确定哪个目录项尚未售出:
SELECT c.catalog_num, c.stock_num, c.manu_code, i.quantity
FROM catalog c LEFT JOIN items i
ON c.stock_num = i.stock_num AND c.manu_code = i.manu_code
WHERE i.quantity IS NULL AND c.manu_code = "HRO";
WHERE 子句包含后连接过滤器,定位目录中尚未被出售的 HRO 项的那些行。
当您在对连接的主部分或从部分中的基础表应用后连接过滤器时,您可提升性
能。要了解更多信息,请参阅您的 GBase 8s 性能指南 。
使用连接作为外连接的主部分或从部分
以 ANSI 连接语法,您可嵌套连接。您可使用连接作为外连接或内连接的主部分
或从部分。
假设您想要修改先前的查询(后连接过滤器示例)来获得更多信息,帮助您确定
是否继续保留该目录中的每一未售出项。您可修改该查询来包括来自 stock 表的
信息,以便能看到带有其成本的每一未售出项的简短描述:
SELECT c.catalog_num, c.stock_num, s.description, s.unit_price,
s.unit_descr, c.manu_code, i.quantity
FROM (catalog c INNER JOIN stock s
ON c.stock_num = s.stock_num
AND c.manu_code = s.manu_code)
LEFT JOIN items i
ON c.stock_num = i.stock_num
AND c.manu_code = i.manu_code
WHERE i.quantity IS NULL
AND c.manu_code = "HRO";
在此示例中,在 catalog 与 stock 表之间的内连接形成带有 items 表的外连接的
主部分。
要了解外连接的附加示例,请参阅 GBase 8s SQL 教程指南。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 895
GBase 8s 扩展外连接
OUTER 关键字
对于外连接的 GBase 8s 扩展语法始于隐式的左外连接。即,您以 OUTER 关键
字开始 GBase 8s 扩展外连接。
这是 GBase 8s 扩展 OUTER 子句的语法。
GBase 8s OUTER 子句

下列示例使用 OUTER 关键字来创建罗列所有客户及其订单的外连接,不论他们
是否已下订单:
SELECT c.customer_num, c.lname, o.order_num FROM customer c,
OUTER orders o WHERE c.customer_num = o.customer_num;
此带有在 orders 表中相匹配的行从 customer 表返回所有行。如果在 orders 表
中没有客户的记录出现,则对那些有 NULL 值的客户返回的 order_num 列。
如果您有复合的外连接,即,该查询有多个外连接,则您必须或者嵌入附加的外
连接或者在圆括号中连接,如语法图所示,或在 WHERE 子句中的主表与每一从
表之间创建连接条件或关系。
当 WHERE 子句中的表达式或条件关系到两个从表时,您必须在 FROM 子句中使用
圆括号将连接的表括起来,以强调主-从关系,如此例中所示:
SELECT c.company, o.order_date, i.total_price, m.manu_name
FROM customer c,
OUTER (orders o, OUTER (items i, OUTER manufact m))
WHERE c.customer_num = o.customer_num
AND o.order_num = i.order_num
AND i.manu_code = m.manu_code;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 896
当您在 FROM 子句中省略括起从表的圆括号时,您必须在 WHERE 子句中的主
表与每一从表之间建立连接条件。如果连接条件在两个从表之间,则查询失败。
然而,下列示例成功地返回结果

将主表 customer 与子表 orders 连接

并将主表 customer 与从表 cust_calls 连接:
SELECT c.company, o.order_date, c2.call_descr
FROM customer c, OUTER orders o, OUTER cust_calls c2
WHERE c.customer_num = o.customer_num
AND c.customer_num = c2.customer_num;
GBase 8s SQL 教程指南 有复合的外连接的示例。
对 GBase 8s 扩展外连接的限制
如果您对于外连接使用此 GBase 8s 扩展语法,则对同一 SELECT 语句使用所有
下列限制:

您必须对单个查询块中的所有外连接使用 GBase 8s 扩展语法。

您必须在 WHERE 子句中包括连接条件。

您不可以 LEFT JOIN 或 LEFT OUTER JOIN 关键字起始另一外连接。

您不可定义横向的表引用或包括 LATERAL 关键字。

在 GBase 8s 扩展外连接之内,“表引用”语法段不可包括在同一 SELECT
语句中声明的横向的表引用。
(+) 操作符
本版本可以使用(+)形式表现外连接,即用 (+) 来表示两表的连接关系。可以
在 WHERE 条件中使用“(+)”形式的外连接语法来实现多表连接。
例如,在以下示例中,使用 (+) 形式的外连接,连接了 orders 表与 customer
表。
SELECT c.customer_num, c.company, o.order_num,
FROM orders o,customer c
WHERE c.customer_num = o.customer_num(+);
此外连接罗列客户的公司名称、编号和所有相关联的订单编号,如果该客户已下
了订单的话。如果没有,仍罗列公司名称,且为订单编号返回 NULL 值。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 897

此外,WHERE 子句的多个连接条件中既可以包含左外连接又可以包含右外连
接。
例如,在以下示例中,orders 表的使用不同的字段与 customer 表进行左外连
接,与 items 表进行右外连接:
SELECT o.customer_num, c. company, i.order_num
FROM orders o,customer c, items i
WHERE o.customer_num = c.customer_num(+)
AND o.order_num(+)=i.order_num;
其次, WHERE 条件句中可同时包含多个连接条件和多个过滤条件。例如:
SELECT o.customer_num, c.company, i.order_num,
FROM orders o,customer c, items i
WHERE c.customer_num = o.customer_num(+)
AND o.order_num(+)=i.order_num
AND (o.customer_num=’101’or i.stock_num >10 );
此语句在上一示例的基础上添加了(o.customer_num=’101’ or
i.stock_num >10 )的过滤条件。请注意,使用时,OR 关系两端的表达式必须
用括号包围。
另外,使用 ”(+)” 操作符表示外连接具有以下限制:
1)『=』两边不能同时设置(+)。
2)多个连接条件之间必须使用 AND 关键字连接,不支持其它关键字。
3)(+) 操作符只适用于列,不能用于表达式,并且不能与 OR 或 IN 运算符一起
使用。
4)不能使用 (+) 操作符连接同一个表,可以通过采用不同别名方式进行自连接。
5)如果在一个单独的查询块中使用了 (+) 操作符,则所有的外连接都必须使用
(+) 操作符的形式。
6)单次查询中任意两张表不能既左外连接后右连外接。
7)如果使用了 (+) 操作符的外连接形式,则在一个查询块中的其它外连接中不能
使用 LEFT JOIN 或者 LEFT OUTER JOIN 形式。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 898
GRID 子句
使用 GRID 子句来指定跨服务器查询的作用域,该查询的数据源是作为 GBase 8s
网格的节点的数据库服务器的表。
除非会话连接到现有的网格之内的数据库,GRID 子句才是有效的。可通过使用
Enterprise Replication 设施的适当的 cdr 命令和 ifx_grid 例程创建网格。
此语法是对 SQL 的 ANSI/ISO 标准的扩展。
SELECT 语句的 GRID 子句支持下列语法:
GRID 子句

元素
描述
限制
语法
grid
此查询所在作用域之
内的网格的名称
必须存在,且必须通过 cdr define
grid 命令定义
标识符
region 此查询所在作用域中
的区域的名称
必须存在且必须通过 cdr define
region 命令定义
标识符
用法
任何显式地或隐式地包括 GRID 子句的 SELECT 语句都称为网格查询。网格查
询的结果,是来自在每个网格服务器中的带有相同名称和相同模式的跨表的
FROM 子句中的每一表的逻辑 UNION 或 UNION ALL 的符合条件的行。此联
合可包括该网格中跨所有节点的表,或跨这些网格节点的子集,称为区域。
注: 网格查询的 FROM 子句指定的表必须都有相同的模式,且必须满足此主题标
识的其他要求。由于这些限制,所以不是所有的 GBase 8s 网格都可支持网格查
询。
可选的 ALL 关键字

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 899
如果可选的 ALL 关键字紧跟在 GRID 关键字之后,则网格查询的结果是逻辑的
UNION ALL,意味着该网格查询的结果集可包括重复的行。否则,如果您省略
ALL 关键字,则仅从每一参与的服务器的结果的逻辑 UNION 返回 distinct 值。
网格查询的 SET ENVIRONMENT 语句选项
对 SET ENVIRONMENT 语句的两个选项可定义缺省的 GRID 子句,以便于任
何不带有 GRID 子句的后续的 SELECT 语句被解释为包括该缺省的 GRID 子句
的网格查询:
SET ENVIRONMENT SELECT_GRID
此语句可指定网格或区域作为后续的网格查询的缺省的作用域,这些网格查询返
回唯一的符合条件的行的联合。GRID 子句可省略网格查询的网格或区域名称,
为指定的缺省节点返回 UNION 结果。
SET ENVIRONMENT SELECT_GRID_ALL
此语句可指定网格或区域作为后续的网格查询的缺省的作用域,这些网格查询返
回所有符合条件的行的联合,包括重复的行。GRID 子句可省略网格查询的网格
或区域名称,为指定的缺省节点返回 UNION ALL 结果。
在启用 SET ENVIRONMENT 语句的这些选项之一时,SQL 解析器将当前的缺省
GRID 子句应用到不包括显式的 GRID 子句的会话中的每个 SELECT 语句。在
同一时间上的同一会话期间,只有一个缺省的 GRID 子句可起作用。当使用 SET
ENVIRONMENT 语句来设置其他关键字选项使选项生效时,或当为不同的网格
或区域重置同一关键字选项时,会禁用先前设置的缺省值。
您还可通过发出这些 SQL 语句之一来禁用缺省的 GRID 子句:
SET ENVIRONMENT SELECT_GRID DEFAULT;_
SET ENVIRONMENT SELECT_GRID_ALL DEFAULT;
上述每一语句都阻止数据库服务器将当前的会话中的每个后续的查询都解释为网
格查询。除非您在同一会话中定义新的缺省的 GRID 子句,否则,任何后续的
SELECT 语句必须包括显式的 GRID 子句来作为网格查询运行。
在 UNION 查询的 SELECT_GRID 会话环境选项或 UNION ALL 查询的
SELECT_GRID_ALL 会话环境选项已指定了缺省的网格或区域作为当前会话中的
网格查询的作用域时, 您可省略那个网格或区域所在节点上的网格查询中的

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 900
GRID 子句,如下例所示。在此,tab1 和 tab2 是在网格的 region_03 子集之
内的每个网格服务器上的有相同的模式、语言环境和代码集的表:
SET ENVIRONMENT SELECT_GRID 'region_03'
SELECT * FROM tab1;
SELECT * FROM tab2;
执行上述两个查询,就如同您已显式地指定了此 GRID 子句:
SELECT * FROM tab1 GRID 'region_03';
SELECT * FROM tab2 GRID 'region_03';
在同一时点,对于当前的用户会话,对于 SET ENVIRONMENT 语句仅可启用一
个 SELECT_GRID 和 SELECT_GRID_ALL 会话环境选项。当其中一个选项生效
时,使用 SET ENVIRONMENT 语句来设置其他的关键字选项,或重置不同的网
格或区域的同一关键字选项,可禁用先前设置的缺省值。
下列 SQL 语句通过定义不同的缺省的 GRID 子句,组合来自不同区域中的参与
的网格服务器的 UNION ALL 结果,将先前的缺省的 GRID 子句替换为网格的
region_04 子集:
SET ENVIRONMENT SELECT_GRID_ALL 'region_04'
SELECT * FROM tab1;
SELECT * FROM tab2;
将会执行那两个查询,就如同您已制定了此 GRID 子句:
SELECT * FROM tab1 GRID ALL 'region_04';
SELECT * FROM tab2 GRID ALL 'region_04';
在缺省情况下,如果发出网格查询的数据库服务器不可连接到网格或区域之内的
一个或多个节点,显式的或缺省的 GRID 子句指定该网格或区域,则网格查询失
败。即使指定的网格或区域中的有些网格服务器不可用,SET ENVIRONMENT
语句仍可启用的另一会话环境变量可从网格查询返回部分的结果:
SET ENVIRONMENT GRID_NODE_SKIP
当一个或多个网格服务器不可用时,此语句可使得网格查询的处理得以继续。
如果您发出 SQL 语句
SET ENVIRONMENT GRID_NODE_SKIP ON;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 901
,则数据库服务器不论任何不可用的节点,并从参与的网格服务器返回符合条件
的行。您可通过调用 ifx_gridquery_skipped_nodes() 函数来表示任何跳过的节点。
另一函数,ifx_gridquery_skipped_node_count(),可用于检测跳过了多少个节点。
要获取更多关于这些函数的信息,请参阅 GBase 8s Enterprise Replication 指南。
在网格查询的 FROM 子句中的表
在网格查询的 FROM 子句中,仅永久数据库表是有效的。必须通过运行 cdr
change gridtable 命令来将它们定义为网格表。
不支持下列表对象:

表上的同义词或视图,除了 sysmaster 数据库中的表之外

CREATE EXTERNAL TABLE 语句定义的表对象

由数据库服务器或网格服务器的名称限定的表

正在其上执行并发的 ALTER TABLE、ALTER FRAGMENT 或 ALTER
INDEX 操作的表

与参与的网格服务器的数据库中同一名字的其他表有不同的模式的表

不是以相同的数据库语言环境和代码集创建的数据库中的表

跨参与该网格查询的所有数据库,其 SQL_LOGICAL_CHAR 配置参数或
DELIMIDENT 或 GL_USEGLU 环境变量的设置不相同的数据库中的
表。
此外,网格查询的 projection 列表不可包括在跨服务器查询中其数据类型不被支
持的任何列或表达式。不被支持的数据类型包括所有复合的或大对象类型,以及
一些用户定义的类型(UDT)和 opaque 类型。
适用于同一 GBase 8s 示例的跨数据库的分布式 DML 操作中的 DISTINCT 数据
类型的相同限制,也适用于网格查询中的 DISTINCT 数据类型。要获取在分布式
查询中有效的数据类型的讨论,请参阅主题 跨服务器事务中的数据类型 and 分
布式操作中的 DISTINCT 类型。
对网格查询的附加的限制
执行网格查询的用户必须是该网格或区域之内所有节点上的有效用户。
网格查询不可为包含对其外查询引用的子查询。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 902
在其规范之中,网格查询不可引用的任何下列之一:

子查询(但网格查询自身可为其不引用的外查询的子查询)

跨网格服务器的连接操作

导致跨服务器连接的连接请求

在所有参与的网格服务器上都不存在的过程或函数。
在网格查询块中,UNION 或 UNION ALL 集合运算符都不是有效的,
INTERSECT、MINUS 或 EXCEPT 集合运算符也都不是有效的。
GRID 子句不应包括在网格上下文外部的 SELECT 语句中。要获取更多关于网格
的信息,请参阅 SET ENVIRONMENT 语句 和 GBase 8s Enterprise Replication
指南。
SELECT 的 WHERE 子句
WHERE 子句为 GBase 8s 扩展连接指定连接条件,为符合 ANSI 的连接指定后
连接过滤器,和对数据指定搜索条件。
WHERE 子句

元素
描述
限制
语法
Logical_Operator
两个条件
的组合
有效的选项为逻辑并(= OR 或
OR NOT)或逻辑与(= AND 或
AND NOT)
带有 AND
或 OR 的
条件
subquery
内嵌的查

不可包括 FIRST 或 ORDER BY 关
键字
SELECT
语句

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 903
在 WHERE 子句中使用条件
在 WHERE 子句中,您可使用这些简单的条件或比较:

关系运算符条件

IN 或 BETWEEN . . . AND

IS NULL 或 IS NOT NULL

LIKE 或 MATCHES
您还可在 WHERE 子句中使用 SELECT 语句;这称为子查询。在子查询中,下
列 WHERE 子句运算符是有效的:

IN 或 EXISTS

ALL、ANY 或 SOME
要获取更多信息,请参阅 条件。
在 WHERE 子句中,聚集函数不是有效的,除非它是子查询的一部分,或是来源
自父查询的相关的列上,且 WHERE 子句在 HAVING 子句之内的子查询中。
关系运算符条件
如果关系运算符的每一边的表达式满足该表达式指定的关系,则关系运算符条件
是满足的。下列语句使用大于(>)和等于(=)关系运算符:
SELECT order_num FROM orders
WHERE order_date > '6/04/08';
SELECT fname, lname, company
FROM customer
WHERE city[1,3] = 'San';
'San' 需要加上单引号,因为该子字符串来自字符列。请参阅 关系运算符条件。
WHERE 子句中的空格字符串和空字符串
对于 LVARCHAR、NVARCHAR 或 VARCHAR 列,指定列值等于空字符串的
带有 WHERE 子句的查询(
WHERE varlength_col = ''
)返回的结果集,与其中的 WHERE 子句指定等于空格(ASCII 32)字符的字符
串的同一查询是一样的。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 904
例如,如果 varlength_col 是类型 VARCHAR、NVARCHAR 或
LVARCHAR,则下列 WHERE 子句示例在功能上完全等同于指定等于空字符串
的 WHERE 子句:
WHERE varlength_col = ' '
WHERE varlength_col = ' '
WHERE varlength_col = ' '
因此,对于内建的可变长度字符数据类型,在空字符串与全由一个或多个空白字
符组成的字符串之间,没有区别。(然而,请注意,查询过滤器
WHERE varlength_col IS NULL
不等同于先前的 WHERE 子句示例,且如果 varlength_col 值为 NULL,则
返回一个不同的结果集。
IN 条件
当在该关键字右边的值的列表中包括 IN 关键字左边的表达式时,IN 条件是满足
的。
下列示例展示 IN 条件:
SELECT lname, fname, company FROM customer
WHERE state IN ('CA','WA', 'NJ');
SELECT * FROM cust_calls
WHERE user_id NOT IN (USER );
要获取更多信息,请参阅 IN 子查询。
BETWEEN 条件
当 BETWEEN 左边的值在 BETWEEN 右边的两个值的范围之内时,BETWEEN
条件是满足的。下列示例中的前两个查询在 BETWEEN 关键字之后使用文字
值。第三个查询使用内建的 CURRENT 函数和一个文字间隔来搜索当天与七天前
之间的日期。
SELECT stock_num, manu_code FROM stock
WHERE unit_price BETWEEN 125.00 AND 200.00;
SELECT DISTINCT customer_num, stock_num, manu_code
FROM orders, items
WHERE order_date BETWEEN '6/1/07' AND '9/1/07';
SELECT * FROM cust_calls WHERE call_dtime

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 905
BETWEEN (CURRENT - INTERVAL(7) DAY TO DAY) AND
CURRENT;
要获取更多信息,请参阅 BETWEEN 条件。
使用 IS NULL 和 IS NOT NULL 条件
如果指定的 column 包含 NULL 值,或如果指定的 expression 求值为 NULL,
则 IS NULL 条件是满足的。
如果您使用 IS NOT NULL 谓词,则当 column 包含非 NULL 的值时,或当
expression 求值不为 NULL 时,该条件是满足的。下列示例选择尚未支付的订单
的订单编号和客户编号:
SELECT order_num, customer_num FROM orders
WHERE paid_date IS NULL;
要获取 IS NULL 和 IS NOT NULL 运算符的完整描述,请参阅 IS NULL 和 IS
NOT NULL 条件。
LIKE 或 MATCHES 条件
如果下列任一为真,即符合 LIKE 或 MATCHES 条件:

LIKE 或 MATCHES 关键字前面的列的值与加引号的字符串指定的模式
相匹配。您可在字符串中使用通配符。

LIKE 或 MATCHES 关键字前面的列的值与由跟在 LIKE 或 MATCHES
关键字之后的列指定的模式相匹配。在条件中,右边的列值作为匹配模
式。
在 LIKE 或 MATCHES 条件中指定的列可以为简单的字符数据类型(如
CHAR、LVARCHAR、NCHAR、NVARCHAR 或 VARCHAR)或数值型数据类
型(如 INTEGER、SMALLINT、DECIMAL 或 NUMERIC(p,s)、FLOAT、
SMALLFLOAT、BIGINT、INT8、BIGSERIAL、SERIAL、SERIAL8、
MONEY )。
下列 SELECT 语句返回 customer 表中 VARCHAR 类型的 lname 列以文字字
符串 'Baxter' 开头的所有行。由于该字符串为文字字符串,因此该条件区分大
小写。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 906
SELECT * FROM customer WHERE lname LIKE 'Baxter%' ;
下列 SELECT 语句返回 SG_DEV_ACLINE 表中的 length 列包含数字 '261' 的所
有行。length 列是该表的一数值型字段
SELECT * FROM SG_DEV_ACLINE WHERE length LIKE '%261%' ;
以下 SELECT 语句返回 customer 表中 lname 列的值与 fname 列的值相匹配的
所有行:
SELECT * FROM customer WHERE lname LIKE fname;
下列示例使用反斜线(\)作为缺省的转义字符。通过 DEFAULTESCCHAR 配置
参数或 DEFAULTESCCHAR 会话环境选项设置缺省的转义字符。
以下示例使用带有通配符的 LIKE 条件。第一条 SELECT 语句查找所有球类的
库存商品。第二条 SELECT 语句查找所有包含百分号(%)的公司名称。反斜杠
(\)用作百分号(%)通配符的缺省转义字符。第三条 SELECT 语句使用
ESCAPE 选项和 LIKE 条件从 customer 表中检索 company 列包含百分号
(%)的行。z 用作百分号(%)的转义字符:
SELECT stock_num, manu_code FROM stock
WHERE description LIKE '%ball';
SELECT * FROM customer WHERE company LIKE '%\%%';
SELECT * FROM customer WHERE company LIKE '%z%%' ESCAPE 'z';
下列示例在 SELECT 语句中使用带有通配符的 MATCHES。第一条 SELECT 语
句查找所有球类的库存商品。第二条 SELECT 语句查找所有包含星号(*)的公
司名称。反斜杠(\)用作文字星号( *)字符的缺省转义字符。第三条语句使用
ESCAPE 选项和 MACHES 条件从 customer 表中检索 company 列包含星号
(*)的行。指定 z 字符作为星号(*)字符的转义字符。:
SELECT stock_num, manu_code FROM stock
WHERE description MATCHES '*ball';
SELECT * FROM customer WHERE company MATCHES '*\**';
SELECT * FROM customer WHERE company MATCHES '*z**' ESCAPE 'z';
要获取关于 LIKE 或 MATCHES 表达式中支持的运算对象的数据类型的信息,
请参阅主题 LIKE 和 MATCHES 条件。
IN 子查询
随同 IN 子查询,可返回多个满足 IN 或 NOT IN 条件的行,但仅可返回一列。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 907
此示例展示在 SELECT 语句中 NOT IN 子查询的使用:
SELECT DISTINCT customer_num FROM orders
WHERE order_num NOT IN
(SELECT order_num FROM items
WHERE stock_num = 1);
要获取附加的信息,请参阅 IN 条件。
EXISTS 子查询
从 EXISTS 子查询,可返回那些在一个或多个列中的满足 EXISTS 条件的行。
(类似地,NOT EXISTS 子查询可返回在一列或多列中满足 NOT EXISTS 条件
的那些行。)
下列带有 NOT EXISTS 子查询的 SELECT 语句返回那些从未被订购的每项的库
存编号和生产商代码(因而未罗列在 items 表中)。
在此 SELECT 语句中使用 NOT EXISTS 子查询是恰当的,因为您需要相关联的子
查询来同时测试 items 表中的 stock_num 和 manu_code。
SELECT stock_num, manu_code FROM stock
WHERE NOT EXISTS
(SELECT stock_num, manu_code FROM items
WHERE stock.stock_num = items.stock_num AND
stock.manu_code = items.manu_code);
如果您在列名称的位置在子查询中使用 SELECT *,则前一示例同样奏效,因为
您正在测试一行或多行是否存在。
要获取附加的信息,请参阅 EXISTS 子查询条件。
ALL、ANY、SOME 子查询
下列示例返回所有包含一项的所有订单的订单编号,该项的总价大于订单编号
1023 中每项的总价。第一个 SELECT 使用 ALL 子查询,第二个 SELECT 通
过使用 MAX 聚集函数产生相同的结果。
SELECT DISTINCT order_num FROM items
WHERE total_price > ALL (SELECT total_price FROM items
WHERE order_num = 1023);


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 908
SELECT DISTINCT order_num FROM items
WHERE total_price > SELECT MAX(total_price) FROM items
WHERE order_num = 1023);
下列 SELECT 语句返回所有包含一项的所有订单的订单编号,该项的总价大于订
单编号 1023 中至少一项的总价。第一个 SELECT 语句使用 ANY 关键字,而
第二个 SELECT 语句使用 MIN 聚集函数:
SELECT DISTINCT order_num FROM items
WHERE total_price > ANY (SELECT total_price FROM items
WHERE order_num = 1023);

SELECT DISTINCT order_num FROM items
WHERE total_price > (SELECT MIN(total_price) FROM items
WHERE order_num = 1023);
如果子查询恰好返回一个值,则您可在子查询中省略关键字 ANY、ALL 或
SOME。如果您省略 ANY、ALL 或 SOME,且子查询返回多个值,则您会收到
错误。下一示例中的子查询仅返回一行,因为它使用聚集函数:
SELECT order_num FROM items
WHERE stock_num = 9 AND quantity =
(SELECT MAX(quantity) FROM items WHERE stock_num = 9);
另请参阅 ALL、ANY 和 SOME 子查询。
在 WHERE 子句中指定连接
您在 WHERE 子句中通过创建关系来连接两表,在来自一表的至少一列与来自另
一表的至少一列之间连接。该连接创建临时的合成表,其中的满足连接条件的每
一行对相连接形成单行。
连接

数据源

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 909

元素
描述
限制
语法
alias
为表或视图在 FROM 子句中
声明的临时的可替代名称
请参阅 自连接;FROM
子句
标识符
column
要被连接的表或视图的列
必须在表或视图中存

标识符
external
要从其检索数据的外部表
外部表必须存在
数据库对
象名
synonym、
table、
view
在查询中要被连接的同义
词、表或视图的名称
同义词和它指向的表
或视图必须存在
数据库对
象名
当指定的列的值之间相匹配时,来自该表或视图的列是连接的。当要被连接的列
有相同的名称时,您必须以其数据源来限定每一列名称。
双表连接
您可创建双表连接、多表连接、自连接和外连接( GBase 8s 扩展语法)。下列
样例展示双表连接:
SELECT order_num, lname, fname FROM customer, orders
WHERE customer.customer_num = orders.customer_num;
多表连接
多表连接是多于两个表的连接。它的结构类似于双表连接的结构,除了您在
WHERE 子句中有对于多于一对表的连接条件。当来自不同的表的列有相同的名
称时,您必须以它的相关联的表或表别名来限定列名称,如在 table.column 中。
要获取表名称的完整语法,请参阅 数据库对象名。
下列多表连接产生订购了一项的客户的公司名称及其库存编号和生产商代码:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 910
SELECT DISTINCT company, stock_num, manu_code
FROM customer c, orders o, items i
WHERE c.customer_num = o.customer_num
AND o.order_num = i.order_num;
自连接
您可将表连接到自身。要这样做,您必须在 FROM 子句中列出该表名称两次,
并为它指定两个不同的表别名。在 WHERE 子句中使用别名来引用这两个表中的
每一个。下一示例是 stock 表上的自连接。它找到库存项的对,其单价差一个大
于 2.5 的系数。字母 x 和 y 分别为 stock 表的两个别名。
SELECT x.stock_num, x.manu_code, y.stock_num, y.manu_code
FROM stock x, stock y WHERE x.unit_price > 2.5 * y.unit_price;
GBase 8s 扩展外连接
下一外连接罗列客户的公司名称和所有相关联的订单编号,如果该客户已下了订
单的话。如果没有,仍罗列公司名称,且为订单编号返回 NULL 值。
SELECT company, order_num FROM customer c, OUTER orders o
WHERE c.customer_num = o.customer_num;
要获取更多关于外连接的信息,请参阅 GBase 8s SQL 教程指南。
层级查询子句
层级子句对表对象上的递归查询设置条件,在该表对象的行之中,存在父子依赖
的层级。包括此子句的 SELECT 语句称为层级查询。
必须在 SELECT 语句的 FROM 子句中指定在其上进行层级查询操作的表对象。
该表对象通常是自引用表,在其中一个或多个列作为同一表中另一列(或这些列
的子集)的外键约束。
层级查询对若干行进行操作,在其中一个或多个列值对应于父子关系的逻辑结构
之内的节点。如果父行有多个孩子,则在同一父母的孩子行之中存在兄弟关系。
例如,这些关系可能反映一个组织的部门和管理级别之内的员工与管理者之中的
报告结构。
此子句支持的语法是对 SQL 的 ANSI/ISO 标准的扩展。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 911
语法
层级子句

必须在 SELECT 语句的 FROM 子句中指定层级查询在其上操作的那些表对象。
该表对象可为下列表对象中的任何一种:

表或可更新的视图

临时表

该会话连接到的同一 GBase 8s 实例的另一数据库中的表

作为查询的结果的派生的表

受到基于标签的访问控制(LBAC)安全策略保护的表

带有列级加密或行级加密的表

任何其他表对象的同义词。
在层级查询的 FROM 子句中,不支持下列表对象:

两个或多个表的连接

不可更新的视图

远程 GBase 8s 实例的数据库中的表

CREATE EXTERNAL TABLE 语句定义了的外部表

序列对象。
GBase 8s 支持在层级查询的 projection 列表中的序列对象,在 WHERE 子句
中,以及在表达式在 SELECT 语句中为有效的其他上下文中,但不在层级查询子
句中。
在相关联的子查询和在不相关联的子查询中,层级子句是无效的。
层级查询可包括所有类型的优化程序伪指令,这些是例外:

连接顺序伪指令

连接方法伪指令
层级查询不支持 GBase 8s 的“并行数据库查询”(PDQ)特性。
层级子句可在表上指定递归的查询,该表的行描述父子关系的层级。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 912

该层级可为简单的层级,诸如组织的报告结构,其中每个非根的节点向该
层级之内的高级的单个节点报告。 (在 GBase 8s 的 LBAC 安全特性
中,TREE 类型的安全标签组件有简单的层级的逻辑结构。)

层级子句可查询更复杂拓扑的数据层级,其中的节点有多对多关系,且其
中的孩子节点可为其父母的祖先。要了解关于使用层级子句来查询在数据
层级之内有循环的信息,请参阅 CONNECT BY 子句。
重要: 层级查询对某些数据集合最为有效,其中的表内的父子依赖有简单图的逻
辑拓扑。如果自引用表包括对相同列集合的多个独立的层级,或如果任何孩子行
还是其父母的祖先,则请参阅 不是简单图的依赖样式。
注: 层级子句与表层级无关,在一系列类型表的模式之中存在父子关系的层级。
类似地,全都来自通用基础类型的一系列 DISTINCT 数据类型的层级与数据层级
类似,但与层级子句无关,层级存在于数据实体之间的父子依赖中,而不是数据
类型之中的关系。
特定于层级查询的 SQL 语法
除了为包含层级数据的表的递归查询指定条件的 START WITH、CONNECT BY
和 CONNECT NOCYCLE BY 关键字之外,层级查询还支持那些仅在层级查询中
才有效的语法令牌,以及在没有 CONNECT BY 子句的 SELECT 语句中不可使
用的语法令牌。 特定于层级查询的语法令牌包括两个运算符、三个伪列和一个内
建的函数:

CONNECT_BY_ROOT 运算符
此运算符可为其运算对象的根祖先返回一表达式。

PRIOR 运算符
此运算符可引用从前一递归步骤返回的值(此处的“步骤”是指该递归查询
的一次迭代)。

LEVEL 伪列
此伪列返回一整数,指示该层级之内递归查询的哪一步骤返回了行。

CONNECT_BY_ISCYCLE 伪列
此伪列可指示一行是否有一个还是其祖先的孩子。

CONNECT_BY_ISLEAF 伪列

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 913
此伪列可指示一行在查询返回的行之中是否有任何的孩子。

SYS_CONNECT_BY_PATH 函数
此函数可构建和返回一字符串,该字符串表示从指定的行到层级的根的路


在 ORDER BY 子句中的 SIBLINGS 关键字
ORDER SIBLINGS BY 子句可对返回的每个级别的同一父母的兄弟行进行
排序。
伪列是在特定的上下文中 SQL 解析器可识别的内建的标识符,共享同一命名空
间作为列和变量。通常在 SELECT 语句的 Projection 子句中指定这些伪列和
SYS_CONNECT_BY_PATH 函数,但可在层级子句中指定 LEVEL 伪列和
PRIOR 运算符。
要获取仅支持层级查询的这些令牌的语法和语义的详细信息,请参阅 在
CONNECT BY 子句中的条件 和 ORDER SIBLINGS BY 子句。
层级查询概述
按下列次序处理包括层级子句的 SELECT 语句的子句:
1. FROM 子句(仅对于当前数据库中的单个表对象)
2. Hierarchical 子句
3. WHERE 子句(无连接断言)
4. GROUP BY 子句
5. HAVING 子句
6. Projection 子句
7. ORDER BY 子句
ORDER BY 子句的 ORDER BY SIBLING 选项可对同一父母的孩子行的集合进行
排序。
包括层级子句的子查询按部分的顺序返回中间结果集,在此,特定层级的迭代
(n+1)中产生的行紧跟在产生它们的迭代(n)中的行之后。然而,ORDER BY

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 914
子句、GROUP BY 或 HAVING 子句,或在 Projection 子句中指定的 DISTINCT
或 UNIQUE 关键字会销毁那部分的顺序。
层级子句跟在 SELECT 语句子句的词汇序列中的 WHERE 子句之后,但在该层
级子句的结果上处理 WHERE 子句断言。如果 SELECT 语句包括层级子句,则
WHERE 子句不可指定连接子句,但在 FROM 子句中指定的表对象可作为连接
一个或多个表的查询的结果集。
任何包括层级查询子句的 SELECT 语句都称为层级查询,在 FROM 子句指定的表
上执行查询的递归序列:
1. 可选的 START WITH 子句可指定条件。返回任何满足此条件的行作为该
层级查询的第一个中间结果集。
2. 下一步骤将在 CONNECT BY 子句中指定的条件应用到表。返回任何满
足那个条件的行作为第二个中间结果集。
3. 下一步骤将 CONNECT BY 条件应用到表。返回的任何行构成第三个中
间结果集。
4. CONNECT BY 子句递归地运行查询来产生连续的中间结果集,直到迭代
产生空结果集为止。
5. 然后,层级 SELECT 语句组合前面的递归步骤的所有中间结果集,产生
该层级子句的最终结果集。
6. 然后,将 WHERE 子句的断言应用到该层级子句检索了的这个行集合,
然后按罗列的顺序应用 SELECT 语句的剩余的子句。
在 START WITH 和 CONNECT BY 子句返回所有中间的结果集之后,您可使用
ORDER SIBLINGS BY 子句来对该层级之内的每个级别的有相同的父母的兄弟行
进行排序。要获取更多信息,请参阅 ORDER SIBLINGS BY 子句。
您可使用来自 SET EXPLAIN 语句的输出来查看层级查询的执行路径。
层级子句提供一种有效的替代机制,使用节点数据库扩展来从层级数据集检索信

层级数据集的示例

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 915
在接下来的几个主题中,那些展示层级查询的 SQL 代码示例是基于下
列 employee 表中的层级数据,其行包含关于在组织的层级之内的员工
的信息。mgrid 列展示员工向其汇报的管理者的员工标识符
(empid):
CREATE TABLE employee(
empid INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(10),
salary DECIMAL(9, 2),
mgrid INTEGER
);
employee 表中 17 行的数据值如下。
INSERT INTO employee VALUES ( 1, 'Jones', 30000, 10);
INSERT INTO employee VALUES ( 2, 'Hall', 35000, 10);
INSERT INTO employee VALUES ( 3, 'Kim', 40000, 10);
INSERT INTO employee VALUES ( 4, 'Lindsay', 38000, 10);
INSERT INTO employee VALUES ( 5, 'McKeough', 42000, 11);
INSERT INTO employee VALUES ( 6, 'Barnes', 41000, 11);
INSERT INTO employee VALUES ( 7, 'O''Neil', 36000, 12);
INSERT INTO employee VALUES ( 8, 'Smith', 34000, 12);
INSERT INTO employee VALUES ( 9, 'Shoeman', 33000, 12);
INSERT INTO employee VALUES (10, 'Monroe', 50000, 15);
INSERT INTO employee VALUES (11, 'Zander', 52000, 16);
INSERT INTO employee VALUES (12, 'Henry', 51000, 16);
INSERT INTO employee VALUES (13, 'Aaron', 54000, 15);
INSERT INTO employee VALUES (14, 'Scott', 53000, 16);
INSERT INTO employee VALUES (15, 'Mills', 70000, 17);
INSERT INTO employee VALUES (16, 'Goyal', 80000, 17);
INSERT INTO employee VALUES (17, 'Urbassek', 95000, NULL);
每一 empid 与 mgrid 值对表达引用的关系,带有适当的 CONNECT BY 条件的
查询的递归迭代可正确地组装成层级。
在此,最后一行中 mgrid 列中的 NULL 值展示其 empid 值为 17 的员工
Urbassek 是此报告层级的根节点。
下图展示 employee 表数据的报告层级(以展示 empid 值的节点)的四个级别:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 916
图: 在报告层级中的元素的关系


START WITH 子句
可选的 START WITH 子句指定条件。满足此条件的行成为层级查询中开启
CONNECT BY 子句的递归操作的根。
START WITH 子句是对 SQL 的 ANSI/ISO 标准的扩展。
语法

用法
START WITH 子句指定 CONNECT BY 子句为其递归活动的第一迭代使用的搜
索条件。如果您省略 START WITH 子句,则 CONNECT BY 子句对于中间结果
的初始集将每行都作为层级的根处理。
CONNECT BY 子句
CONNECT BY 子句为执行层级查询中的递归操作指定条件。
CONNECT BY 子句是对 SQL 的 ANSI/ISO 标准的扩展。
语法


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 917
用法
如果您包括 START WITH 子句,则它指定的搜索条件应用于为层级查询生成第
一个中间结果集。这由那些在 FROM 子句中指定的表中满足 START WITH 条
件为真的行构成。
如果省略 START WITH 子句,则没有可用的 START WITH 条件作为过滤器,
且第一个中间结果集是 FROM 子句指定的表中的行的全集。
通过应用 CONNECT BY 搜索条件,CONNECT BY 子句生成连续的中间结果
集,直到当迭代生成空结果集时此递归过程终结为止。
NOCYCLE 关键字
由 CONNECT BY 子句的递归查询返回的行必须为简单的层级的一部分。 如果
该查询返回一行,该行既是另一节点的祖先又是另一节点的后代,则包括该层级
子句的 SELECT 语句失败并报错。此拓扑称为循环。
您可在 CONNECT BY 关键字与 CONNECT BY 子句的条件规范之间包括
NOCYCLE 关键字来过滤掉任何会导致层级查询失败并报错 -26079 的那些行,
出错的原因是在中间的结果集中有循环。
例如,对于在主题 层级查询子句 中描述的 employee 表的层级数据集,下列
UPDATE 语句会引起其 empid 值为 5 和 17 的员工的循环:
UPDATE employee SET mgrid = 5 WHERE name = 'Urbassek';
在通过上述 UPDATE 语句修改了层级数据集之后,下列查询(省略 NOCYCLE
关键字)失败:
SELECT empid, name, mgrid , CONNECT_BY_ISLEAF leaf
FROM employee
START WITH name = 'Goyal'
CONNECT BY PRIOR empid = mgrid;
当最后的 CONNECT BY 步骤检测到员工 McKeough 是循环的一部分时,发出
错误 -26079:
Empid name mgrid leaf

16 Goyal 17 0
14 Scott 16 1

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 918
12 Henry 16 0
9 Shoeman 12 1
8 Smith 12 1
7 O'Neil 12 1
11 Zander 16 0
6 Barnes 11 1
5 McKeough 11 0

26079: CONNECT BY query resulted in a loop/cycle.
Error in line 8
Near character position 28
您可在 CONNECT BY 关键字与 CONNECT BY 子句的条件规范之间包括
NOCYCLE 关键字来过滤掉会导致层级查询失败并报错 -26079 的任何行,该错
误是由于在中间的结果集中有循环所致。下列查询在 CONNECT BY 子句中包括
NOCYCLE 关键字,这与在 Projection 子句中包括 CONNECT_BY_ISCYCLE 伪
列而导致失败的查询不同。
SELECT empid, name, mgrid, CONNECT_BY_ISLEAF leaf,
CONNECT_BY_ISCYCLE cycle
FROM employee
START WITH name = 'Goyal'
CONNECT BY NOCYCLE PRIOR empid = mgrid;

empid name mgrid leaf cycle

16 Goyal 17 0 0
14 Scott 16 1 0
12 Henry 16 0 0
9 Shoeman 12 1 0
8 Smith 12 1 0
7 O'Neil 12 1 0
11 Zander 16 0 0
6 Barnes 11 1 0
5 McKeough 11 0 0
17 Urbassek 5 0 1
15 Mills 17 0 0
13 Aaron 15 1 0
10 Monroe 15 0 0

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 919
4 Lindsay 10 1 0
3 Kim 10 1 0
2 Hall 10 1 0
1 Jones 10 1 0

17 row(s) retrieved.
由于 NOCYCLE 关键字使得在检测到了循环之后 CONNECT BY 子句能够继续
处理,从在先前的示例中失败了的 CONNECT BY 步骤返回了 Urbassek,并继
续处理直到已返回了该结果集中的所有行为止。在上述输出显示中,leaf 为
CONNECT_BY_ISLEAF 伪列的别名,且 cycle 为 CONNECT_BY_ISCYCLE 伪
列的别名,在 Projection 子句中同时声明两个别名。在这些结果中,Urbassek 在
cycle 中被标记为循环的起因。
上述结果集表明,通过更改该行中的 mgrid 值,该行已识别了 McKeough 作为
Urbassek 的管理者,可从 employee 表移除循环:
UPDATE employee SET mgrid = NULL WHERE empid = 17;
在 CONNECT BY 子句中的条件
在布尔条件和在一般的 SQL 表达式中,除了表达式和运算符是有效的之外,在
CONNECT BY 子句中指定的 condition 支持另外两种语法结构,仅在包括层级子
句的 SELECT 语句中,PRIOR 运算符和 LEVEL 伪列才是有效的。
PRIOR 运算符
PRIOR 一元运算符可被包括在 CONNECT BY 子句中,以列名称作为它的运算
对象。PRIOR 可用于将 CONNECT BY 子句的最近的先前递归步骤的结果的列
引用,与对当前结果集的列引用区分开来。列名称紧跟在此右关联的运算符之
后,如下列语法片断所示:

CONNECT BY mgrid = PRIOR empid
此处,在 mgrid 中指定管理者的那些行满足 CONNECT BY 条件,在先前的迭
代中与员工值相匹配的列在 empid 列中。
PRIOR 运算符可应用于比列名称更复杂的表达式。下列条件使用算术表达式作为
PRIOR 的运算对象:

CONNECT BY PRIOR (salary - 10000) = salary

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 920
在同一 CONNECT BY 条件中,可以多次包括 PRIOR 运算符。另请参阅主题
层级查询子句,该主题提供一个在 CONNECT BY 子句的条件中使用 PRIOR 运
算符的层级查询的示例。
LEVEL 伪列
伪列是与列名称共享同一命名空间的 SQL 的关键字,在某些其中的列表达式为
有效的上下文中那是有效的。
LEVEL 是返回在返回了行的层级子句中迭代步骤的序号的伪列。对于由 START
WITH 子句返回的所有行,LEVEL 返回值 1。通过应用 CONNECT BY 子句的
第一个迭代返回的行返回 2。通过 CONNECT BY 的连续的迭代返回的行有增量
为 1 的 LEVEL 值,因此 LEVEL = (N + 1) 表明为第 N 次 CONNECT BY 迭
代返回的值。LEVEL 列的数据类型是 INTEGER。
下列层级查询的样例在 Projection 子句的选择列表中指定 LEVEL:
SELECT name, LEVEL FROM employee START WITH name = 'Goyal'
CONNECT BY PRIOR empid = mgrid;
该查询返回这些结果:
name level

Goyal 1
Zander 2
McKeough 3
Barnes 3
Henry 2
O'Neil 3
Smith 3
Shoeman 3
Scott 2

9 row(s) retrieved.
在包括层级子句的 SELECT 语句的 Projection 子句中,以及在 CONNECT BY
子句的 condition 中,可包括 LEVEL。
然而,在下列上下文中,LEVEL 伪列不是有效的:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 921

没有 CONNECT BY 子句的 SELECT 语句

层级子句的 START WITH condition

CONNECT_BY_ROOT 运算符的运算对象

SYS_CONNECT_BY_PATH 函数的参数。
仅在层级查询中有效的附加的语法
下列语法令牌支持层级查询,且仅在层级查询中是有效的。 然而,不同于
PRIOR 运算符和 LEVEL 伪列,它们在层级子句中不是有效的:

CONNECT_BY_ISCYCLE 伪列

CONNECT_BY_ISLEAF 伪列

CONNECT_BY_ROOT 一元运算符

SQL 的 SYS_CONNECT_BY_PATH( ) 函数。
CONNECT_BY_ISCYCLE 伪列
如果在层级中的下一级该行可能循环,则 CONNECT_BY_ISCYCLE 是返回 1
的伪列。即,该行有一个直接的孩子,该孩子又是在 CONNECT BY 子句中指定
的搜索条件给出的祖先。如果该行不直接地导致循环,则该列返回 0。仅当在
CONNECT BY 子句中指定 NOCYCLE 时,才有可能为非 0 的值。此列的数据
类型是 INTEGER。
下列 UPDATE 语句在 employee 表的数据层级中创建循环:
UPDATE employee SET mgrid = 5 WHERE empid = 17;
下列层级查询在 Projection 子句中包括 CONNECT_BY_ISCYCLE 伪列,但在它
遇到 UPDATE 语句创建的循环的步骤中,CONNECT BY 子句抛出错误。
SELECT empid,
name,
mgrid,
CONNECT_BY_ISLEAF leaf,
CONNECT_BY_ISCYCLE cycle
FROM employee
START WITH name = 'Goyal'
CONNECT BY PRIOR empid = mgrid;

665: Internal error on semantics -

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 922
CONNECT_BY_ISCYCLE is used without NOCYCLE parameter..
Error in line 1
Near character position 72
在它遇到 UPDATE 语句创建的循环的步骤中抛出错误的 CONNECT BY 子句
中,通过指定 NOCYCLE,此查询可避免 -655 错误。
SELECT empid, name, mgrid,
CONNECT_BY_ISLEAF leaf, CONNECT_BY_ISCYCLE cycle
FROM employee
START WITH name = 'Goyal'
CONNECT BY NOCYCLE PRIOR empid = mgrid;
要获取此查询的结果,请参阅在主题 CONNECT BY 子句 中的对 NOCYCLE 关
键字的描述的示例。
在下列上下文中,CONNECT_BY_ISCYCLE 伪列不是有效的:

没有 CONNECT BY 子句的 SELECT 语句

START WITH 或 CONNECT BY 子句

CONNECT_BY_ROOT 运算符的运算对象

SYS_CONNECT_BY_PATH 函数的参数
CONNECT_BY_ISLEAF 伪列
如果该行如 CONNECT BY 所定义的那样是层级中的叶子,则
CONNECT_BY_ISLEAF 是返回 1 的伪列。如果节点在查询结果层级中(不是在
实际的数据层级中)没有孩子,则该节点是叶节点。如果该行不是叶子,则该列
返回 0。该列的数据类型是 INTEGER。
下列层级查询在 Projection 子句中指定 CONNECT_BY_ISLEAF 伪列,并声明
leaf 为那列的别名,在 DB-Access 中的结果集显示为:
SELECT empid, name, mgrid, CONNECT_BY_ISLEAF leaf
FROM emp1oyee
START WITH name = 'Goyal'
CONNECT BY PRIOR empid = mgrid;

empid name mgrid leaf

16 Goyal 17 0

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 923
14 Scott 16 1
12 Henry 16 0
9 Shoeman 12 1
8 Smith 12 1
7 O'Neil 12 1
11 Zander 16 0
6 Barnes 11 1
5 McKeough 11 1

9 row(s) retrieved.
CONNECT_BY_ROOT 运算符
对于层级中的每行,CONNECT_BY_ROOT 一元运算符接受表达式作为它的运算
对象,该表达式求值为层级的一个节点的行。CONNECT_BY_ROOT 返回它的运
算对象的根祖先的表达式。

该 expression 运算对象可为任何 SQL 表达式,但它必须不包含任何层级查询
令牌,包括下列令牌:

CONNECT_BY_ROOT 或 PRIOR 一元运算符

CONNECT_BY_ISCYCLE、CONNECT_BY_ISLEAF 或 LEVEL 伪列

SYS_CONNECT_BY_PATH 函数。
此右关联的运算符的返回数据类型是指定的表达式的数据类型。
下列示例中的层级查询从 employee 表返回行,既包括员工要向其直接地报告的
管理者的标识编号,也包括位于此查询的层级的根的管理者的名称。
SELECT empid, name, mgrid, CONNECT_BY_ROOT name AS topboss
FROM employee
START WITH name = 'Goyal'
CONNECT BY PRIOR empid = mgrid;

empid name mgrid topboss

16 Goyal 17 Goyal
14 Scott 16 Goyal

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 924
12 Henry 16 Goyal
9 Shoeman 12 Goyal
8 Smith 12 Goyal
7 O'Neil 12 Goyal
11 Zander 16 Goyal
6 Barnes 11 Goyal
5 McKeough 11 Goyal

9 row(s) retrieved.
在下列上下文中,CONNECT_BY_ROOT 运算符不是有效的:

没有 CONNECT BY 子句的 SELECT 语句

START WITH 或 CONNECT BY 子句

SYS_CONNECT_BY_PATH 函数的参数
SYS_CONNECT_BY_PATH 函数
在包括层级子句的 SELECT 语句中调用 SYS_CONNECT_BY_PATH ( ) 函数是
有效的,但不可从层级子句调用此函数。如果您尝试在 START WITH 或
CONNECT BY 子句的 condition 之内运行此函数,则 GBase 8s 返回错误。
在层级查询中,SYS_CONNECT_BY_PATH 函数可用来构建表示路径的字符串,
该路径从对应于根节点的行至当前行。
这是 SYS_CONNECT_BY_PATH 的调用语法,返回在 LEVEL N 的指定行的字符串:
SYS_CONNECT_BY_PATH 函数

元素
描述
限制
语法
format_string
通常是作为运算符的
常量字符串

引用字符

string_expression
标识行的表达式。
不可包括层级查询
令牌
表达式

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 925
SYS_CONNECT_BY_PATH 构建表示路径的字符串,通过递归地串联连续的返回
值,该路径从根到该层级的 LEVEL N 的指定的行:

path1 := string_expression1||format_string 表示从第一个中间的结果集到
根行的路径,

path2 := path1||string_expression2||format_string 求值为从根到在第二个
中间的结果集中的行的路径,

. . .

pathN := path(N-1)||string_expressionN||format_string 求值为从根到第
N 个中间的结果集的路径。
SYS_CONNECT_BY_PATH 的参数中的表达式必须不包括任何层级查询结构,包
括下列结构:

CONNECT_BY_ROOT 或 PRIOR 一元运算符

CONNECT_BY_ISCYCLE、CONNECT_BY_ISLEAF 或 LEVEL 伪列

SYS_CONNECT_BY_PATH 函数。
在参数列表中也无效的是聚集表达式。
从 SYS_CONNECT_BY_PATH ( ) 的返回值是 LVARCHAR(4000) 类型。
下列示例中的层级查询调用在 Projection 列表中的 SYS_CONNECT_BY_PATH
函数,以 employee.name 列和斜线(/)字符作为它的参数。
SELECT empid, name, mgrid, SYS_CONNECT_BY_PATH( name,'/') as
hierarchy
FROM employee
START WITH name = 'Henry'
CONNECT BY PRIOR empid = mgrid;
该查询返回数据层级的子集之内的行,其中在 START WITH 子句中指定 Henry
作为根,展现每一员工和员工的管理者的名称和 empid 编号,以及在该层级中到
Henry 的路径。CONNECT BY 子句使用相等断言 PRIOR empid = mgrid 来
返回向管理者报告的员工(在此情况下,仅 Henry),通过先前的步骤返回了其
empid。该查询的结果集是:
empid 12
name Henry
mgrid 16
hierarchy /Henry

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 926

empid 9
name Shoeman
mgrid 12
hierarchy /Henry/Shoeman

empid 8
name Smith
mgrid 12
hierarchy /Henry/Smith

empid 7
name O'Neil
mgrid 12
hierarchy /Henry/O'Neil

4 row(s) retrieved.
这些行按检索它们的顺序罗列:

START WITH 子句在此层级的根返回了 Henry 行。

CONNECT BY 子句的第一个步骤返回了三行,对应于向 Henry 报告的
三名员工。

下一 CONNECT BY 步骤未返回行,因为由先前的步骤返回的
Shoeman、Smith 和 O'Neil 都是此层级之内的叶节点,对其 PRIOR
empid = mgrid 条件求值为假。
查询执行结束,展示返回的四行,此处,hierarchy 是
SYS_CONNECT_BY_PATH( name,'/') 为每一行返回到 Henry 的路径的别名。
(在第一个返回的行中,字符串 /Henry 展示 Henry 的根状态。)
不是简单图的依赖样式
您可在包括复合的依赖的数据集上运行递归层级查询,诸如多根节点,或孩子节
点的多父节点。然而,基于层级的数据树结构,可能发生循环,且可能返回更多
的记录。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 927
CONNECT BY 子句不可分析包括循环的数据集,其中有些孩子节点标识为它们
的父节点的祖先。如果您的数据集包括循环,则该循环可能是包含无效数据的行
的产物。
如果自引用的表描述的数据集包括多个层级,则包括带有条件的 START WITH
子句,该条件仅对于您想要该递归查询返回的层级的根为真。请对每一层级在表
上运行分别的查询,使用不同的 START WITH 子句来指定每一查询中的根。
GROUP BY 子句
使用 GROUP BY 子句来为每一组产生单行结果。组是在此子句中引用的每一列
(或列表达式)的有相同值的行的集合。
GROUP BY 子句

元素
描述
限制
语法
col_alias
列名称的别名
必须已在 Projection
子句中声明
标识符
column
通过此列(或此表达
式)的值将行成组
请参阅 GROUP BY 与
Projection 子句之间
的依赖。
标识
符、表
达式
select_number
指定在 Projection 子
句的选择列表中的列或
表达式的次序位置的整

请参阅 使用选择编
号。
精确数

table_object
包含 column 的表或视
图的名称、同义词或别

必须存在且必须在
FROM 子句中指定
标识符

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 928
带有 GROUP BY 子句的 SELECT 语句为在 column 中有相同的值的,或在
col_alias 引用的列中有相同的值的,或在 select_number 指定的列或表达式中有
相同的值的每一组行返回单一的结果行。
在 NLSCASE INSENSITIVE 数据库中,在 NCHAR 和 NVARCHAR 数据上的
排序和字符串比较时,不管字母大小写的区别,因此,数据库服务器将由相同序
列字母组成的字符串之中的大小写变量视作完全相同。对于在 NCHAR 或
NVARCHAR 列上的成组数据的查询,如果某些限定的行仅字母的大小写不同,
则与在区分大小写的数据库中在同一数据集上的同一查询的组数相比,该组的数
目较少。要获取更多关于在以 NLSCASE INSENSITIVE 属性创建了的数据库中
的数据处理的更多信息,请参阅 在 NLSCASE INSENSITIVE 数据库中重复的行
和 在区分大小写的数据库中的 NCHAR 和 NVARCHAR 表达式。
GROUP BY 与 Projection 子句之间的依赖
GROUP BY 子句限制 Projection 子句可指定的内容。如果您包括 GROUP BY 子
句,则还必须在 GROUP BY 子句中引用 Projection 子句的选择列表中的每一
column。
如果您在包括 GROUP BY 子句的查询的选择列表中指定聚集函数以及一个或多
个列表达式,则必须包括在 GROUP 子句中用作聚集或时间表达式的一部分的所
有列名称。
如果在 projection 子句中指定 OLAP 窗体函数,则在 GROUP BY 子句中还必须
包括该 OLAP 窗体函数之内所有的列引用。
如果您在选择列表中为列声明别名,则可在 GROUP BY 子句中以那个别名代替
该列名称,在 GROUP BY 子句中需要该列的名称或别名之一。
在 GROUP BY 列表中常量表达式和 BYTE 或 TEXT 列表达式不是有效的。
如果选择列表包括 BYTE 或 TEXT 列,则您不可使用 GROUP BY 子句。此
外,您不可在 GROUP BY 子句中包括 ROWID。
如果选择列表包括用户定义的数据类型的列,则不可在 GROUP BY 子句中使用
该列,除非该 UDT 可使用内建的 bit-hashing 函数。必须以 CANNOTHASH 修
饰符创建不可使用该内建的 bit-hashing 函数的任何 UDT,其告诉数据库服务器
不可在 GROUP BY 子句中使用该 UDT。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 929
下列示例指定不在聚集表达式中的一列。 total_price 列不应在 GROUP BY 列表
中,因为它是作为聚集函数的参数出现。COUNT 和 SUM 聚集被应用到每一组,而
不是该查询的整个结果集。
SELECT order_num, COUNT(*), SUM(total_price)
FROM items GROUP BY order_num;
如果选择列表中的列表达式仅是列名称,则您必须在 GROUP BY 子句中使用它
的名称或它的别名。如果通过算术运算符将列与另一列组合,则您可选择以两种
方式中的一种来成组该查询结果集:

通过单个列的名称或别名,

抑或,通过使用 select number 的组合的表达式,指定 Projection 子句的
选择列表之内的表达式的次序位置的文字整数。
GROUP BY 子句中的 NULL 值
在罗列在 GROUP BY 子句中的列中,包含 NULL 值的每一行属于单个组。也就
是说,将所有的 NULL 值组在一起。
使用选择编号
您可在 GROUP BY 子句中使用一个或多个整数来代表列表达式。在下一示例
中,第一个 SELECT 语句在 GROUP BY 子句中使用 order_date 和 paid_date -
order_date 的选择编号。您仅可通过使用选择编号的组合的表达式来成组。
在第二个 SELECT 语句中,您不可以数学表达式 paid_date - order_date 来代
替 2:
SELECT order_date, COUNT(*), paid_date - order_date
FROM orders GROUP BY 1, 3;
SELECT order_date, paid_date - order_date
FROM orders GROUP BY order_date, 2;
HAVING 子句
使用 HAVING 子句来将一个或多个限定的条件应用到组或应用到整个结果集。
HAVING 子句


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 930
在下列示例中,每一条件将该组的一个计算的属性与该组的另一计算的属性或常
量进行比较。第一个 SELECT 语句使用 HAVING 子句,将计算的表达式
COUNT(*) 与常量 2 进行比较。该查询返回有两个以上项的所有订单上每项的
平均合计价格。
第二个 SELECT 语句罗列那些在同一个月中呼叫两次或更多次的客户的客户及其
呼叫月份:
SELECT order_num, AVG(total_price) FROM items
GROUP BY order_num HAVING COUNT(*) > 2;
SELECT customer_num, EXTEND (call_dtime, MONTH TO MONTH)
FROM cust_calls GROUP BY 1, 2 HAVING COUNT(*) > 1;
您可使用 HAVING 子句来在 GROUP BY 列值上以及在计算的值上设置条件。
此示例返回 cust_code 和 customer_num、call_dtime,并从 customer_num 小
于 120 的客户已收到的所有呼叫的 call_code 来将它们分组:
SELECT customer_num, EXTEND (call_dtime), call_code
FROM cust_calls GROUP BY call_code, 2, 1
HAVING customer_num < 120;
HAVING 子句通常是对 GROUP BY 子句的补充。 如果您省略 GROUP BY 子
句,则 HAVING 子句应用于满足该查询的所有行,以及在组成单个组的表中的
所有行。下列示例返回该表中所有值的平均价格,只要表中有十行以上:
SELECT AVG(total_price) FROM items HAVING COUNT(*) > 10;
由于在 WHERE 子句中的条件不可包括聚集表达式,所以您可使用 HAVING 子
句来将带有聚集的条件应用于查询的整个结果集,如上例所示。
在 HAVING 子句中的条件不可包括 DISTINCT 或 UNIQUE 聚集表达式。例
如,下列查询失败并报语法错误:
SELECT order_num, COUNT(*) number, AVG (total_price) average
FROM items
GROUP BY order_num
HAVING COUNT(DISTINCT *) > 2;
然而,如果从上述示例省略 DISTINCT 关键字,则不发出错误。
ORDER BY 子句
ORDER BY 子句按指定的列或表达式对查询结果排序。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 931
ORDER BY 子句

子字符串

元素
描述
限制
语法
column
按此列中的值对行排序 无
标识符
display_label
列或列表达式的临时名

在 Projection 子句
中声明的标签之中必
须是唯一的
标识符
first、last
在要对结果集排序的列
子串中的第一个和最后
一个字节
整数;仅限于 BYTE、
TEXT 和字符数据类型
精确数值
select_number
在 Projection 子句的
选择列表中列的次序位

请参阅 使用选择编
号。
精确数值
table
包含 column 的表或视
图的名称、同义词或别

必须存在且必须在
FROM 子句中指定
标识符
ORDER BY 子句表明该查询返回多行。在 SPL 中,如果您指定 ORDER BY 子
句而没有 FOREACH 循环来处理 SPL 例程之内单个地返回的行,则数据库服务
器发出错误。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 932
下列查询在 FROM 子句中指定派生的表,按照 col1 值对其行排序,并声明 vtab
作为派生的表的名称,且 vcol 作为其唯一列的名称:
SELECT vcol FROM
(SELECT FIRST 5 col1 FROM tab1 ORDER BY col1) vtab(vcol);
在 NLSCASE INSENSITIVE 数据库中的 ORDER BY
在以 NLSCASE INSENSITIVE 属性创建的数据库中,对 NCHAR 或
NVARCHAR 数据类型的列和表达式的操作不区分大写字母和小写字母。因此,
包括 ORDER BY 子句的查询可能以不管变量的字母大小写的序列返回行,如果
该列或表达式为 NLS 数据类型,且该数据包括仅字母大小写不同的值。
如果数据集包括同一字符串的字母大小写变量,则按重复来处理这些,带有按它
们的检索顺序罗列的大小写变量。例如,被处理为重复的一系列 NCHAR 或
NVARCHAR 字符串可能按此顺序出现:
gAMma
GAmma
GaMMa
gamma
GAMMA
要获取更多信息,请参阅 在 NLSCASE INSENSITIVE 数据库中重复的行 和 在
区分大小写的数据库中的 NCHAR 和 NVARCHAR 表达式。
按列或按表达式排序
要按表达式对查询结果排序,您还必须为在 Projection 子句中的表达式声明显示
标签,如下例所示,为两列之间的差异声明显示标签 span:
SELECT paid_date - ship_date span, customer_num FROM orders
ORDER BY span;
GBase 8s 支持在 ORDER BY 子句中使用列和表达式,它们不会出现在
Projection 子句的选择列表中。可以忽略选择列表中的派生列的显示标签,并通过
ORDER BY 子句中的选择编号指定派生列。
然而,如果下列任一为真的话,那么 Projection 子句的选择列表必须包括所有
ORDER BY 子句指定的列或表达式:

该查询包括 DISTINCT、UNIQUE 或 UNION 运算符。

该查询包括 INTO TEMP table 子句。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 933

分布式查询访问远程数据库,其服务器要求 ORDER BY 子句中的每个列
或表达式还要出现在 Projection 子句的选择列表中。

ORDER BY 子句中的表达式包括列子字符串的显示标签。(请参阅下一
部分 按子字符串排序。)
下一查询从 orders 表选择一列,并按照另一列的值对结果排序。缺省情况下,
按升序罗列这些行。
SELECT ship_date FROM orders ORDER BY order_date;
本版 GBase 8s 支持当 SELECT 投影列仅包含聚集表达式列时,无需 GROUP
BY 子句即可按该表达式排序,例如:
SELECT MAX(ship_weight)
FROM orders ORDER BY ship_weight;
但是,当SELECT 投影列不仅包含了聚集表达式列,还包含了其它列时,查询中
必须具有 GROUP BY 子句才能按照聚集表达式排序。如下所示:
SELECT ship_charge, MAX(ship_weight)
FROM orders GROUP BY ship_charge ORDER BY ship_weight;
如果当前的处理语言环境定义了本地化顺序,那么 NCHAR 和 NVARCHAR 列
的值会以本地化的顺序进行排序。
在 GBase 8s 中,ORDER BY 子句中的任何 column 均不能为集合类型,但其结
果集定义集合派生表的查询可包括 ORDER BY 子句。要了解示例,其参阅 集合
派生表。
如果增加 DS_NONPDQ_QUERY_MEM 配置参数的设置,那么可以提升一些使
用 ORDER BY 子句对很大的行的集合进行排序的非 PDQ 查询的性能。
按子字符串排序
您可按照子字符串排序,而不是按照字符、BYTE 或 TEXT 列的整个长度,或按
照返回字符串的表达式排序。数据库服务器使用该子字符串来对结果集排序。通
过指定整数下标( first 和 last 参数)来定义该子字符串,表示在该列值之内子
字符串的起始和终止字节位置。
下列 SELECT 语句查询 customer 表,并在 ORDER BY 列中指定列子字符串。这
会指导数据库服务器通过包含在列值的第六至第九字节中的 lname 列的一部分来
对查询结果排序。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 934
SELECT * from customer ORDER BY lname[6,9];
假设在 customer 表的一行中的 lname 的值为 Greenburg。由于 ORDER BY
子句中的列子字符串,数据库服务器通过使用值 burg 来确定此行的排序位置,
而不是通过整个列值 Greenburg。
当按照表达式排序时,您可仅为返回字符数据类型的表达式指定子字符串。如果
您在 ORDER BY 子句中指定列子字符串,则该列必须有下列数据类型中的一
种:BYTE、CHAR、NCHAR、NVARCHAR、TEXT 或 VARCHAR。
GBase 8s 还可支持 ORDER BY 子句中的 LVARCHAR 列子字符串,如果该列
在本地数据库服务器的数据库中的话。
要获取关于使用在 ORDER BY 子句中的列子字符串的 GLS 方面的信息,请参
阅 GBase 8s GLS 用户指南。
按 CASE 表达式排序
ORDER BY 子句可包括 CASE 表达式来指定排序键。
在下列示例中,表 tab_case 的列 a_col 为 INT 类型。对表 tab_case 的查询
包括 Projection 列表中的列 a_col 和聚集表达式 SUM(a_col),并通过 a_col
的值将结果分组。ORDER BY 子句指定两个排序键:

紧跟在 ORDER BY 关键字之后的 CASE 表达式

AVG(a_col) 聚集表达式:
CREATE TABLE tab_case(a_col INT, b_col VARCHAR(32));

SELECT a_col, SUM(a_col)
FROM tab_case
GROUP BY a_col
ORDER BY CASE
WHEN a_col IS NULL
THEN 1
ELSE 0 END ASC,
AVG(a_col);


GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 935
在此,ASC 关键字显式地将 CASE 表达式的结果标识为升序排序键。在缺省情
况下,AVG(a_col) 排序键也指定升序排序。
在下列类似的示例中,基于同一 tab_case 表上的查询,第二个 CASE 表达式返
回或者 1 或者 0 作为返回的 AVG(a_col) 聚集值的排序键值。
SELECT a_col, SUM(a_col)
FROM tab_case GROUP BY a_col
ORDER BY CASE
WHEN a_col IS NULL
THEN 1
ELSE 0 END ASC,
AVG(a_col),
CASE
WHEN AVG(a_col) IS NULL
THEN 1
ELSE 0 END;
升序和降序
您可使用 ASC 和 DESC 关键字来指定升序(最小值在先)或降序(最大值在
先)。
缺省的顺序为升序。对于 DATE 和 DATETIME 数据类型,最小的意思是时间
上最早的,最大的意思是时间上最晚的。对于在缺省的语言环境中的字符数据类
型,该顺序为 ASCII 顺序序列,如 U.S. English 数据的排序顺序 中所列。
对于 NCHAR 或 NVARCHAR 数据类型,使用当前会话的本地化顺序排序,如
果那与代码集顺序不同的话。要获取更多关于排序的信息,请参阅 SET
COLLATION 语句。
如果您指定 ORDER BY 子句,则在缺省情况下,NULL 值的排序小于非 NULL
值。使用 ASC 顺序,则 NULL 值排在任何非 NULL 值之前;使用 DESC 顺
序,则 NULL 排在最后。
指定 NULL 值的顺序
ORDER BY 子句可包括 NULLS FIRST 关键字或 NULLS LAST 关键字来显式地
(抑或覆盖)展示 NULL 值的缺省的排序顺序:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 936

NULLS FIRST 关键字指示数据库服务器将 NULL 值排在排序的查询结
果的最前面。按降序排序,ASC NULLS FIRST 关键字请求缺省的顺序。
在降序排序中,DESC NULLS FIRST 指定在排序键列中的带有 NULL 值
的行排在排序的结果集中非 NULL 行的前面。

NULLS LAST 关键字指示数据库服务器将 NULL 值排在排序的查询结果
的最后面。在降序排序中,DESC NULLS LAST 关键字请求缺省的顺序。
在降序排序中,ASC NULLS LAST 指定在排序键列中的带有 NULL 值的
行跟在排序的结果集中非 NULL 行之后。
嵌套排序
如果您在 ORDER BY 子句中罗列多个列,则您的查询按照嵌套的排序排列。排
序的第一级是基于第一列的;第二列决定排序的第二级。下列嵌套排序的示例选
择 cust_calls 表中的所有行,通过 call_code 之内的 call_code 和
call_dtime 对它们进行排序:
SELECT * FROM cust_calls ORDER BY call_code, call_dtime;
使用选择编号
在列名称的位置,您可在 ORDER BY 子句中输入一个或多个整数,来引用罗列
在 Projection 子句的选择列表中所罗列的项的位置。您还可使用选择编号来按表
达式排序。
下列示例使用嵌套排序中的选择编号来按照表达式 paid_date - order_date 和
customer_num 排序:
SELECT order_num, customer_num, paid_date - order_date
FROM orders
ORDER BY 3, 2;
当通过 UNION 或 UNION ALL 关键字连接 SELECT 语句时,或当在同一位置
中相兼容的列有不同的名称时,在 ORDER BY 子句中需要选择编号。
按 Rowid 排序
您可在 ORDER BY 子句中指定 ROWID 关键字。这指定 rowid 列,在为分片
的表以及以 WITH ROWIDS 子句创建了的分片的表中的隐藏列。rowid 列包含

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 937
与表中的行相关联的唯一的内部记录编号。(然而,建议您使用主键作为您的访
问方法,而不是利用 rowid 列。)
如果您正在从其选择的表是一个没有 rowid 列的分片的表,则 ORDER BY 子句
不可指定 rowid 列。
当您在 ORDER BY 子句中指定 ROWID 时,您不需要在 Projection 子句中包括
ROWID 关键字。
要获取关于 rowid 值以及如何在列表达式中使用 rowid 列的进一步的信息,请
参阅 WITH ROWIDS 选项 和 使用 Rowid。
带有 DECLARE 的 ORDER BY 子句
在 GBase 8s ESQL/C 中,您不可使用带有 FOR UPDATE 子句的 DECLARE 语
句来将游标与没有 ORDER BY 子句的 SELECT 语句相关联。
在 ORDER BY 列上设置索引
当您在 SELECT 语句中包括 ORDER BY 子句时,您可通过在 ORDER BY 子句
指定的一列或多列上创建索引来提升查询的性能。数据库服务器使用您在
ORDER BY 列上设置的索引来以最高效的方式对查询结果排序。要获取更多关于
如何创建与 ORDER BY 子句的列相对应的索引的信息,请参阅 使用 ASC 和
DESC 排序顺序选项。
ORDER SIBLINGS BY 子句
ORDER SIBLINGS BY 子句仅在层级查询中是有效的。 可选的 SIBLINGS 关键
字指定首先对父行排序,以及然后对该层级之内每个级别的每一父行的孩子行进
行排序的顺序。
有些行有 SIBLINGS BY 关键字之后指定的列中的值的重复列表,这些行在带有相
同的值列表和相同的父行的那些行之中是任意排序的。如果层级查询包括不带有
SIBLINGS 关键字的 ORDER BY 子句,则根据那些跟在 ORDER BY 关键字之后的排
序规范来排列行的顺序。在层级查询中,既不需要 ORDER BY 子句,也不需要
ORDER BY 子句的 ORDER SIBLINGS BY 选项。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 938
在下列示例中的层级查询返回层级数据集中的行的子集,其根为 Goyal,如主题
层级查询子句 中罗列的那样。 此查询包括 ORDER SIBLINGS BY 子句来按照
name 对那些报告给同一管理者的员工进行排序:
SELECT empid, name, mgrid, LEVEL
FROM employee
START WITH name = 'Goyal'
CONNECT BY PRIOR empid = mgrid
ORDER SIBLINGS BY name;
以下列顺序对此查询返回的行进行排序:
empid name mgrid level

16 Goyal 17 1
12 Henry 16 2
7 O'Neil 12 3
9 Shoeman 12 3
8 Smith 12 3
14 Scott 16 2
11 Zander 16 2
6 Barnes 11 3
5 McKeough 11 3

9 row(s) retrieved.
在此,START WITH 子句返回了在此层级的根部的 Goyal 行。 两个后续的
CONNECT BY 步骤(在 level 伪列中标记为 2 和 3)返回三个兄弟行的集
合:

Henry、Scott 和 Zander 是其父母为 Goyal 的兄弟;

O'Neil、Shoeman 和 Smith 是其父母为 Henry 的兄弟;

Barnes 和 McKeough 使其父母为 Zander 的兄弟。
下一 CONNECT BY 步骤未返回行,因为符合 level = 3 的那些行是此层级中的
叶节点。在该查询的此执行点上,将 ORDER SIBLINGS BY 应用于结果集,按
上述顺序对这些行排序。
由于该排序键 name 为 VARCHAR 列,因此在每一兄弟的集合之内的返回的行
都按照它们的 employee.name 值的 ASCII 顺序排列。仅在返回的行的层级中为
叶节点的那些兄弟的集合在排序的结果集中连续地出现,因为管理者紧跟在向他

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 939
们报告的员工之后,而不是他们的兄弟。此示例中的例外是 Scott,其孩子节点形
成空集。
ORDER BY 子句中的 SIBLINGS 关键字是对 SQL 语言的 ISO 标准语法的扩
展。如果您在不包括有效的 CONNECT BY 子句的查询或子查询的 ORDER BY
子句中包括 SIBLINGS 关键字,则 SELECT 语句失败并报错。
要获取更多关于层级查询和 CONNECT BY 子句的信息,请参阅 层级查询子
句。
在 SELECT 语句的 ORDER BY 子句中的 OLAP window
函数
您可在不包括 CONNECT BY 子句的那些 SELECT 子句的最终的 ORDER BY
子句中包括 OLAP window 函数。
如果在 ORDER BY 子句中出现 OLAP 函数子句,则在 ORDER BY 求值之前,
先求值 OLAP 函数。
一般地说,对于包括一个或多个 OLAP window 函数的简单的 SELECT 语句,数
据库服务器遵循下列处理次序:

将任何连接、过滤器、GROUP BY 或 HAVING 规范应用于获取符合条
件的行的集合,来作为查询集合返回。

创建符合条件的行的 window 分区,并将指定的 OLAP 函数应用于每一
分区结果集(或应用于这个查询结果集,如果未定义分区的话)中的每一
行。

将 SELECT 语句的 ORDER BY 子句应用于最终的查询结果。
对于嵌套查询,每一子查询都遵循上述顺序,但将 OLAP window 分区及其
OLAP 函数应用于最里面的子查询的结果集,在其中定义该 OLAP window。
如果 OLAP window 包括 window ORDER 子句,则那个子句,而不是 SELECT
语句的 ORDER BY 子句,定义 window ROW_NUMBER 函数在同一 OLAP
window 的分区中分配给这些行的行编号。然而,window ORDER 子句不定义查
询结果集的排序,由 SELECT 语句的 ORDER BY 子句定义。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 940
如果 OLAP window 不包括 window ORDER 子句,则以任意的顺序排列 window
ROW_NUMBER 函数分配给这些行的行编号,如查询或子查询返回的那样,而不
是根据 SELECT 语句的任何 ORDER BY 子句。
对 STANDARD 或 RAW 结果表排序
当 SELECT INTO Table 子句定义要存储查询的结果的永久表时,那个子句中的
任何非平凡的列表达式还必须为新创建的结果表中相应的列声明别名。要指定那
一列作为结果表的排序键,ORDER BY 子句还必须引用相同的别名,而不是指定
非平凡的列表达式。
例如,在下列嵌套查询中,tab56 是结果表的标识符,且 tab56_col0 是子查询在
Projection 子句中定义的非平凡的列表达式的别名。ORDER BY 子句指定相同的
子查询作为排序键,而不是通过它的别名引用那个非平凡的列:
SELECT ( SELECT tab54.tab54_col7 tab56_col0
FROM tab54
WHERE (tab54.tab54_col7 = -1423023 )
) tab56_col0,
"" tab56_col1
FROM tab57
WHERE tab57.tab57_col1 == -6296233
ORDER BY (
SELECT tab54.tab54_col7 tab56_col0
FROM tab54
WHERE (tab54.tab54_col7 = -1423023 )
) NULLS FIRST,2 NULLS FIRST
INTO tab56;
在正常的 SELECT 语句中,在 ORDER BY 子句中指定非平凡的列表达式是可接
受的,但在对一由 SELECT INTO Table 子句创建了的结果表进行排序的 ORDER
BY 子句中是不可接受的。在上述示例中,数据库服务器返回 SQL 错误 -
19828。
要避免此错误,必须修改上述示例,将非平凡的列表达式从 ORDER BY 子句移
除,以它的别名取代那个表达式:
SELECT ( SELECT tab54.tab54_col7 tab56_col0
FROM tab54

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 941
WHERE (tab54.tab54_col7 = -1423023 )
) tab56_col0,
"" tab56_col1
FROM tab57
WHERE tab57.tab57_col1 == -6296233
ORDER BY
tab56_col0 -- Substituted alias for column expression in result table)
NULLS FIRST,2 NULLS FIRST
INTO tab56;
FOR UPDATE 子句
当您打算更新由准备好的 SELECT 语句返回的值,当存取这些值时,请在
ESQL/C 应用中和在 DB-Access 中使用 FOR UPDATE 子句。
准备包含 FRO UPDATE 子句的 SELECT 语句,等同于准备不带有 FOR UPDATE 子
句的 SELECT 语句,然后为准备好的语句声明 FOR UPDATE 游标。
FOR UPDATE 子句

元素
描述
限制
语法
column 在 FETCH 之后可被
更新的列的名称
必须在 FROM 子句 table 中存在,
但不需要在 Projection 列表中。所
有的列必须都来自同一表。
标识符
FOR UPDATE 关键字通知数据库服务器可能会有更新,导致它使用比随同 Select
游标更严格的锁。不带有此子句,您不可通过游标修改数据。您可指定哪些列可
被更新。
在您为 SELECT . . . FOR UPDATE 语句声明游标之后,您可使用带有 WHERE
CURRENT OF 子句的 UPDATE 或 DELETE 语句更新或删除当前选择了的行。关键字
CURRENT OF 引用最近存取了的行;它们替代在 WHERE 子句中的通常的条件表达
式。要以特定的值更新行,您的程序可能包含诸如下列示例中的语句:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 942
EXEC SQL BEGIN DECLARE SECTION;
char fname[ 16];
char lname[ 16];
EXEC SQL END DECLARE SECTION;
. . .

EXEC SQL connect to 'stores_demo';
/* select statement being prepared contains a for update clause */
EXEC SQL prepare x from 'select fname, lname from customer for update';
EXEC SQL declare xc cursor for x;

for (;;)
{
EXEC SQL fetch xc into $fname, $lname;
if (strncmp(SQLSTATE, '00', 2) != 0) break;
printf("%d %s %s\n",cnum, fname, lname );
if (cnum == 999) --update rows with 999 customer_num
EXEC SQL update customer set fname = 'rosey' where current of xc;
}

EXEC SQL close xc;
EXEC SQL disconnect current;
SELECT . . . FOR UPDATE 语句,像 Update 游标一样,允许您执行那些单独使
用 UPDATE 语句不可能执行的更新,因为对更新的决定以及新的数据项的值都
可基于该行的原始内容。UPDATE 语句不可查询正在被更新的表。
注: 在游标的 FETCH 循环内部的正常的更新不可确保在 UPDATE 之后再次存取
更新了的行。WHERE CURRENT OF 规范将 UPDATE 联系到 Update 游标,并确保每
一行仅更新一次,通过在内部保持一个已被更新了的行的列表。这些行将不被
Update 游标再次存取。
与 FOR UPDATE 子句不兼容的语法
包括 FOR UPDATE 子句的 SELECT 语句必须符合下列限制:

该语句可仅从一个表选择数据。

该语句不可包括任何聚集函数。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 943

该语句不可包括任何下列子句或关键字:DISTINCT、EXCEPT、FOR
READ ONLY、GROUP BY、INTO TEMP、INTERSECT、INTO
EXTERNAL、MINUS、ORDER BY、UNION、UNIQUE。

将游标与该语句关联的 DECLARE 语句还不可包括 FOR UPDATE 关键
字。

该语句仅在 ESQL/C 例程中和(在事务之内)在 DB-Access 实用程序中
是有效的。例如,不可在 SPL 例程之内发出它。
要获取关于如何为一不包括 FOR UPDATE 子句的 SELECT 语句声明 update 游
标的信息,请参阅 使用 FOR UPDATE 选项。
在 SPL 例程中更新游标
您不可在 SPL 的 FOREACH 语句的 SELECT . . . INTO 段中包括 FOR
UPDATE 关键字。然而,SPL 例程可提供 FOR UPDATE 游标的功能

通过在 FOREACH 语句中声明 cursor 名称,

然后使用 UPDATE 或 DELETE 语句中的 WHERE CURRENT OF
cursor 子句,对同一 FOREACH 循环之内的那个 cursor 的当前行进行
操作。
FOR READ ONLY 子句
请使用 FOR READ ONLY 关键字来指定为 SELECT 语句声明了的 Select 游标
是只读游标。 只读游标是不可修改数据的游标。此部分提供关于 FOR READ
ONLY 子句的下列信息:

您何时必须使用 FOR READ ONLY 子句

对于使用 FOR READ ONLY 子句的 SELECT 语句的语法限制
以只读方式使用 FOR READ ONLY 子句
通常,您无需在 SELECT 语句中包括 FOR READ ONLY 子句。根据定义,
SELECT 是只读操作,因此 FOR READ ONLY 子句通常是没有必要的。然而,
在某些环境下,您必须在 SELECT 语句中包括 FOR READ ONLY 关键字。
在符合 ANSI 的数据库中,在缺省情况下,Select 游标是 update 游标。update
游标是可用来修改数据的游标。这些 update 游标与数据库的只读方式是不兼容
的。例如,针对 customer_ansi 表的此 SELECT 语句失败:
EXEC SQL declare ansi_curs cursor for

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 944
select * from customer_ansi;
解决方法是在您的 Select 游标中包括 FOR READ ONLY 子句。此子句指定的只
读游标与数据库的只读模式相兼容。例如,下列针对 customer_ansi 表的
SELECT FOR READ ONLY 语句成功:
EXEC SQL declare ansi_read cursor for
select * from customer_ansi for read only;
DB-Access 以 Select 游标执行所有的 SELECT 语句,因此,您必须在所有访问
只读的符合 ANSI 的数据库中数据的查询中指定 FOR READ ONLY。FOR READ
ONLY 子句导致 DB-Access 将 SELECT 语句的游标声明为只读游标。
要获取更多关于 0 级备份的信息,请参阅 GBase 8s 备份与恢复指南。要获取关
于 Select 游标、只读游标和 update 游标的信息,请参阅 DECLARE 语句。
与 FOR READ ONLY 子句不兼容的语法
如果您尝试在同一 SELECT 语句中包括 FOR READ ONLY 子句和 FOR
UPDATE 子句,则该 SELECT 语句失败。要获取关于为不包括 FOR READ
ONLY 子句的 SELECT 语句声明只读游标的信息,请参阅 DECLARE 语句。
INTO table 子句
使用 INTO Table 子句来创建新的临时的、永久的或外部的表来接收 SELECT 语
句检索的数据。
INTO table

元素
描述
限制
语法
table 要接收查询结果的
表在此声明的名称
在当前数据库中您拥有的表、视图、同
义词和序列对象之中,必须是唯一的
标识符

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 945
您必须对要在其上创建临时的、永久的或外部表的数据库有 Connect 权限。在其
他用户会话中的临时表的标识符之中,临时表的名称无需是唯一的。
在 Projection 子句中,必须指定在永久的、临时的或外部表中的列名称,在此,
您必须为不是简单的列表达式的所有表达式提供显示标签。该显示标签成为在永
久的、临时的或外部表中的列名称。如果您没有为简单的列表达式声明显示标
签,则产生的新表使用 Projection 子句的选择列表中的列名称。
下列 INTO TEMP 示例创建 pushdate 表,带有两个列 customer_num 和
slowdate:
SELECT customer_num, call_dtime + 5 UNITS DAY slowdate
FROM cust_calls INTO TEMP pushdate;
下列 INTO STANDARD 示例创建 stab1 表,带有两列 fcol1 和 col2:
SELECT col1::FLOAT fcol1, col2
FROM tab1 INTO STANDARD stab1;
在此,col1 是该查询从其检索数据的 tab1 表中的 INTEGER 列,但 fcol1 值在
产生的 stab1 表中被强制转型为 FLOAT。省略 STANDARD 关键字的查询会创
建相同的结果表,因为 STANDARD 是缺省的表类型。
当没有返回行时的结果
当您使用与 WHERE 子句组合的 INTO Table 子句时,且没有返回行,则
SQLNOTFOUND 值在符合 ANSI 的数据库中是 100,在不符合 ANSI 的数据
库中是 0。如果 SELECT INTO TEMP…WHERE… 语句是多语句 PREPARE 的
一部分,且没有返回行,则对于符合 ANSI 的数据库和不符合 ANSI 的数据库,
SQLNOTFOUND 值都是 100。
此 GBase 8s 版本在遇到 SQLNOTFOUND 值 100 之后,继续处理多语句准备
好的对象的剩余的语句。然而,您可维持传统的行为,通过将
IFX_MULTIPREPSTMT 环境变量设置为 1,不执行剩余的准备好的语句。
对 ESQL/C 中的 INTO table 子句的限制
在 GBase 8s ESQL/C 中,请不要在同一查询中同时使用 INTO table 子句与
INTO variable 子句。如果您同时使用,则不会向程序变量返回结果,且将
SQLCODE 变量设置为负值。要获取更多关于 INTO variable 子句的信息,请参
阅 INTO 子句。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 946
INTO TEMP 子句
INTO TEMP 子句创建临时表来保存查询结果。
INTO TEMP 子句

INTO TEMP 子句创建的临时表的缺省的初始的 extent 和下一 extent 为每个 8
页。通过数据库服务器的内建的 RSAM 访问方式,该临时表必须是可访问的;
您不可指定另一访问方式。
如果您使用同一查询结果一次以上,则使用临时表可节省时间。此外,使用
INTO TEMP 子句常常可以使 SELECT 语句更清晰和易于理解。
临时表中的数据值是静态的;当我们用来构建临时表的表发生更改时,临时表中
的数据并不更新。您可使用 CREATE INDEX 语句来在临时表上创建索引。
日志记录的临时表一直存在,直到发生下列事件之一为止:

应用程序从数据库断开连接。

在临时表上发出 DROP TABLE 语句。

数据库关闭。
无日志记录的临时表存在,直到发生下列事件之一为止:

应用程序从数据库断开连接。

在临时表上发出 DROP TABLE 语句。
如果您的 GBase 8s 数据库没有事务日志记录,则临时表采取的行为与以 WITH
NO LOG 选项创建的表的行为相同。
如果您在 DBSPACETEMP 环境变量中指定多个临时 dbspace(或如果未设置,
在 DBSPACETEMP 配置参数中), 则 INTO TEMP 子句将查询的结果集的行
以轮询方式加载到这些 dbspace 内。要获取更多关于带有 INTO TEMP 子句的查
询创建的临时表的存储位置的信息,请参阅 临时表的存储位置。
由于在无日志记录的临时表上的操作不做日志记录,所以使用 WITH NO LOG 选
项会减轻事务日志记录的负荷。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 947
由于当数据库被关闭时无日志记录的临时表不消失,所以您可使用无日志记录的
临时表来在应用程序保持连接时将数据从一个数据库转移到另一个。您以 INTO
TEMP 子句的 WITH NO LOG 选项创建的临时表的行为与 RAW 表的行为相
似。
要获取更多关于临时表的信息,请参阅 CREATE TEMP TABLE 语句。
INTO STANDARD 和 INTO RAW 子句
您可使用 INTO STANDARD 和 INTO RAW 子句来创建一个新的存储 SELECT
语句的结果集的永久表。
此语法提供单一机制来指定查询,来接收符合条件的记录,并将那些查询结果插
入到永久的数据库表内。
INTO STANDARD 和 INTO RAW 子句

元素
描述
限制
语法
table 为结果表在此声明的名称 在本地数据库中必须尚未存在 标识符
当使用 SELECT INTO 来创建新的永久表时,您可指定它的类型为 STANDARD
或 RAW。缺省的类型是 STANDARD。您可可选地指定新表的存储位置、extent
大小和锁模式选项。
新的永久表的列名称是在 Projection 子句的选择列表中指定的那些名称。如果星
号(*)作为 Projection 子句的选择列表出现,则该星号扩展到 SELECT 语句的
FROM 子句中相应的表或视图的所有列名称。任何影子列都不会通过星号规范来
扩展。
下列示例创建新的名为 ptabl 的 raw 表来存储连接查询的结果:
SELECT t1col1, t1col2, t2col1
FROM tab1, tab2
WHERE t1col1 < 100 and t2col1 > 5
INTO RAW ptab1;

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 948
在上例中,新的 ptabl 表可能包含列 t1col1、t1col2 和 t2col1。
除了简单的列表达式之外的所有表达式都必须有一个定义在 Projection 子句中的
显示标签。此显示标签被用作新表中的列的名称。如果简单的(或平凡的)列表
达式没有显示标签,则该表使用列名称。如果在选择列表中有重复的显示标签或
列名称,则返回错误。
下一示例失败并返回错误 -249,因为它没有为 col1+5 表达式声明显示标签:
SELECT col1+5, col2
FROM tab1
INTO ptab1;
下列修订的查询避免在前一示例中的 -249 错误:
SELECT col1+5 pcol1, col2
FROM tab1
INTO ptab1;
上述修正的示例创建标准 ptabl 表来在它的列 pcol1 和 col2 中存储查询结果。
对结果表的限制
与大部分 DDL 语句一样,使用完全符合条件的表名称在另一数据库中创建新的
结果表的尝试失败并返回语法错误。
要以与同一数据库中现有的表相同的名称创建结果表,也会发生类似的错误。
SELECT INTO . . . TABLE 语句不可被用作子查询的一部分。
然而,您可使用不是 SELECT 子句的 projection 列表的一部分的列作为 ORDER
BY 子句中的排序键。
要获取对于可类似地创建查询结果表并通过插入符合条件的行来填充那表的
CREATE TABLE 语句语法的描述,请参阅 AS SELECT 子句。
INTO EXTERNAL 子句
INTO EXTERNAL 子句将查询结果卸载到外部表内,创建缺省的外部表描述,当
您之后重新加载这些文件时可以使用。
使用 SELECT INTO EXTERNAL 语句的 Table Options 子句来指定在外部表中卸载
的数据的格式。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 949
INTO table 子句

USING Options

Table Options

元素
描述
限制
语法
field_delimiter
分隔字段的字符。
缺省为管道(|)字

如果您未设置
RECORDEND 环境变量,
则 record_delimiter
的缺省值为换行字符
(CTRL-J)。
如果您使用一个不可打
印的字符作为定界符,
则将它编码作为该
ASCII 字符的八进制表
示。例如,'\006' 可表
示 CTRL-F。
引用字
符串
record_delimiter
分隔记录的字符

引用字
符串

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 950
元素
描述
限制
语法
table
在此声明的要接收
查询结果的表的名

在当前数据库中您拥有
的表、视图、同义词和
序列对象的名称之中必
须是唯一的
数据库
对象名
INTO EXTERNAL 子句将 CREATE EXTERNAL TABLE . . . SAMEAS 与
INSERT INTO . . . SELECT 语句的功能组合在一起。
INTO EXTERNAL 子句重写在 EXTERNAL 表中任何先前存在的行。
下表描述应用于卸载数据的关键字。如果您想在外部表描述中为之后重新加载该
表指定附加的表选项,则请参阅 Table 选项。
在 SELECT ... INTO EXTERNAL 语句中,您可指定除了固定的格式选项之外的
在 CREATE EXTERNAL TABLE 语句中讨论的任何表选项。
当创建的数据文件的格式类型或为定界的文本(如果您使用 DELIMITED 关键字
的话)或 GBase 8s 内部的数据格式的文本(如果您使用 GBASEDBT 关键字的
话)时,您可使用 INTO EXTERNAL 子句。您不可将它用于固定的格式卸载。
关键字 作用
DELIMITER 指定在定界的文本文件中分隔字段的字符
ESCAPE 指示数据库服务器识别在基于 ASCII 文本的数据文件中字段
之间作为分隔符嵌入的 ASCII 特殊字符。 紧接在
DELIMITER 指定的 field_delimiter 分隔符的任何实例之前的
缺省的转义字符,此处的那个字符是该数据中的字母值。 或
者您包括或者您省略 ESCAPE 关键字,在缺省情况下,此功
能是被启用的,或者您可指定 ESCAPE ON 关键字来使得您
的 SQL 代码的读者更清楚地了解启用了此特性。要防止在该
数据中的字母的 field_delimiter 分隔符字符被转义,您必须指
定 ESCAPE OFF 关键字。
在缺省情况下,ESCAPE 关键字在字母的 field_delimiter 字符
之前插入的转义字符是反斜杠(\)字符。但如果将

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 951
DEFAULTESCCHAR 配置参数设置为单个字符值,则以那个
字符取代定界符字符的反斜杠(\)用作字母,当指定
ESCAPE 或 ESCAPE ON 时。
FORMAT 指定在该数据文件中的数据的格式
RECORDEND 指定在定界的文本文件中分隔记录的字符
要获取更多关于外部表的信息,请参阅 CREATE EXTERNAL TABLE 语句。
在组合查询中的集合运算符
集合运算符 UNION、UNION ALL、INTERSECT 和 MINUS 可操作指定
Projection 子句中的相同数目的列的两个查询的结果集,且在两个查询的相应的列
中有可兼容的数据类型。
(MINUS 集合运算符有 EXCEPT 作为它的关键字同义词。MINUS 和 EXCEPT
运算符从相同的运算对象返回的结果通常是相同的。)
这些运算符对两个查询的结果集执行基本的集合操作并集、交集和差集,这两个
结果集是这些集合运算符的左运算对象和右运算对象:

UNION 集合运算符将来自两个查询的符合条件的行组合到单个结果集
内,该结果集由一个查询返回的或两个查询都返回的不重复的行组成。
(如果您还包括 ALL 关键字,则 UNION ALL 结果集可包括重复的
行。)

INTERSECT 集合运算符比较来自两个查询的结果集,但仅返回同时在两
个查询的结果集中的不重复的行。

MINUS 集合运算符比较来自两个查询的结果集,但仅返回在左边的查询
的结果集中但不在右边的查询的结果集中的不重复的行。
在业务分析上下文中,集合运算符是有用的。它们还可用在 SELECT 语句中,在
已执行了诸如 UPDATE、INSERT、DELETE 或 MERGE 这样的 DML 操作之
后,来检查数据库的完整性。当您将数据转移到历史表时,可类似地使用集合运
算符,例如,当您需要在从原始的表删除行之前确认在历史表中有正确的数据的
时候。

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 952
所有集合运算符有相同的优先顺序。在包括多个集合运算符的复杂的查询中,运
算符的优先顺序为从左至右。请使用括号来将集合运算符及其运算对象分组,如
果您需要覆盖集合运算符的缺省的从左至右的优先顺序的话。
仅 UNION 集合运算符支持 ALL 关键字。带有 INTERSECT、MINUS 或
EXCEPT 集合运算符的 ALL 关键字是无效的,仅从其返回不重复的行。
当比较行来计算集合并集或差集时,在 INTERSECT 和 MINUS 操作中的两个
NULL 值被认为是相等的。
对组合 SELECT 的限制
对于您通过 UNION、INTERSECT、MINUS 或 EXCEPT 集合运算符进行连接的
查询,会受到以下限制:

每条查询的 Projection 子句中的项数必须相同,且每条 Projection 子句中
的相应项必须有兼容的数据类型。

每条查询的 Projection 子句不能指定 BYTE 或 TEXT 对象(此限制不适
用于 UNION ALL 操作。)

如果使用 ORDER BY 子句,它必须紧跟在最后一条 Projection 子句之
后,而且必须引用整数 select_number 排序(而不是按 SQL 标识符排
序)的项。设置操作完成后,就开始排序。

可以在临时表中存储任何集合运算符的组合结果,但 INTO TEMP 子句只
能出现在最后一条 SELECT 语句中。

在 GBase 8s ESQL/C 中,除非返回的行只有一行,而且您没有使用游
标,否则不能将 INTO 子句用于复合查询。在这种情况下,INTO 子句必
须在第一条SELECT 语句中。
UNION 子查询是在子查询中包括 UNION 运算符的查询。在定义视图的 CREATE
VIEW 语句中,不能指定UNION 子查询。
在组合查询中,本版 GBase 8s 支持在分布式查询中引用 UNION 子查询。即,
可以在本地服务器的不同实例间,或跨服务器的实例间包含 UNION 子查询。
下列限制影响所有组合的查询,包括 UNION 和 UNION ALL 子查询,以及包括
INTERSECT、MINUS 或 EXCEPT 集合运算符的查询:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 953

UNION 子查询不能是触发器事件。如果有效 UNION 子查询指定已在其
中定义 Select 触发器,那么该查询成功,但是忽略该触发器(或视图上
的 INSTEAD OF 触发器)。

在包含 UNION 子查询或任何其他集合运算符的查询中,在 ALL、
ANY、IN、NOT IN 和 SOME 运算符的左边,包括主变量的通用的表达
式是无效的。但是只由单个主变量组成的表达式在此上下文中有效。
例如,在上述限制之下,下列查询是有效的:
SELECT col1 FROM tab1 WHERE ? <= ALL
(SELECT col2 FROM tab2 UNION SELECT col3 FROM tab3);
在此示例中,ALL 左边的表达式是单个主变量( ? ),这是包含 UNION 子查询的
查询中 ALL、ANY、IN、NOT IN 或 SOME 运算符之前受支持的唯一涉及主变
量的表达式。
相反,下列示例显示了无效查询:
SELECT col1 FROM tab1 WHERE (? + 8) <= ALL
(SELECT col2 FROM tab2 UNION SELECT col3 FROM tab3);
该查询失败是因为在 ALL 运算符左边的 <= 关系运算符的操作数是(? + 8)
(包含主变量的算术表达式)。这在 UNION 子查询中是无效语法,在通过任何
其他集合运算符组合查询中也无效。
不包含主变量的表达式不遵守此限制。因此,下列(包括相同的 UNION 子查询
的)查询有效:
SELECT col1 FROM tab1 WHERE (col1 + 8) <= ALL
(SELECT col2 FROM tab2 UNION SELECT col3 FROM tab3);
UNION 运算符
将 UNION 运算符放在两条 SELECT 语句之间来将查询组合到单个查询内。
可以使用 UNION 运算符将几个 SELECT 语句串在一起。相应的项无需具有相
同的名称。可通过省略 ALL 关键字来排除重复的行。
在本版本GBase 8s 中,在包含 UNION 运算符的查询中支持数值型字段和数值
字符串的组合查询。其返回结果的为 DECIMAL(16) 或 DECIMAL(32) (取决于
返回的数值的长度)数据类型。例如:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 954
SELECT 123 FROM tab1 UNION SELECT ‘456’ FROM tab2;
下一示例假定 tab1 表中 colid 列为 INT 类型:
SELECT col1id FROM tab1 UNION SELECT ‘111’ FROM tab2;
使用 UNION 时还可以直接将 NULL 值与其它类型的列值进行组合查询,而无
需强制转换 NULL 的数据类型。其返回结果的类型与 NULL 值对应的其它类型
值的数据类型一致。
例如,在以下示例中假定 tab2 表中 colid 的类型为 VARCHAR:
SELECT NULL as a1 FROM tab1
UNION SELECT colname FROM tab2
INTO tab3;
数据库会自动将上面示例中 NULL 的类型转换为 colname 列的数据类型
VARCHAR。查看 tab3 表的信息:
info columns for tab3;
返回如下:
Column name Type Nulls
A1 varchar(10)
UNION ALL 运算符
如果您使用 UNION ALL 运算符,则从两个查询返回所有符合条件的行,而不排
除任何重复的行。(如果您使用 UNION 运算符而不带 ALL 关键字来组合两个
查询,则从符合条件的行的组合的集合移除任何重复的行。也就是说,如果有多
行,它们每一列包含的值均完全相同,那么只保留一行。)
下一示例使用 UNION ALL 来组合两个 SELECT 语句的结果,而不移除重复行。该
查询返回在 2007 年第一季度与 2008 年第一季度期间接收的所有电话的列表。
SELECT customer_num, call_code FROM cust_calls
WHERE call_dtime BETWEEN
DATETIME (2007-1-1) YEAR TO DAY
AND DATETIME (2007-3-31) YEAR TO DAY
UNION ALL
SELECT customer_num, call_code FROM cust_calls
WHERE call_dtime BETWEEN
DATETIME (2008-1-1)YEAR TO DAY

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 955
AND DATETIME (2008-3-31) YEAR TO DAY;
如果想要从结果集移除重复行,请使用不带关键字 ALL 的 UNION 作为查询之
间的集合运算符。在前一示例中,如果两个 SELECT 语句都返回了组合 101
B,则 UNION 运算符会导致该组合只罗列一次。(如果您想要移除每一
SELECT 语句中的重复行,则请紧接在 Projection 子句的 Select 列表之前使用
DISTINCT 或 UNIQUE 关键字,如同 允许重复 中描述的那样。)
对于指定仅带有 UNION 运算符的集合操作,ALL 关键字是有效的。如果 ALL
紧跟在 INTERSECT、MINUS 或 EXCEPT 集合运算符之后,这些集合运算符排
除重复的部分,则数据库服务器发出错误。
要获取关于数据库服务器如何在有 NLCASE INSENSITIVE 属性的数据库中标识
重复的 NCHAR 或 NVARCHAR 值的信息,请参阅主题 在区分大小写的数据库
中的 NCHAR 和 NVARCHAR 表达式。
子查询中的 UNION
您可在 WHERE 子句、FROM 子句之内的 SELECT 语句的子查询中,以及在集
合子查询中使用 UNION 和 UNION ALL 运算符。然而,在此 GBase 8s 版本
中,在下列上下文中不支持包含 UNION 或 UNION ALL 的子查询:

在视图的定义中

在触发器的事件或 Action 子句中

使用 FOR UPDATE 子句或使用 Update 游标
有关集合子查询的信息,请参阅 集合子查询。关于 FOR UPDATE 子句的更多信
息,请参阅 FOR UPDATE 子句。
特别地是,在本版本数据库中支持在分布式查询中包含 UNION 的子查询。
在组合的子查询中,数据库服务器只能在列的限定表引用的作用域中解析出列
名。例如,下列查询返回错误:
SELECT * FROM t1 WHERE EXISTS
(SELECT a FROM t2
UNION
SELECT b FROM t3 WHERE t3.c IN
(SELECT t4.x FROM t4 WHERE t4.4 = t2.z));

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 956
在此,不可解析最内部的子查询 t2.z,因为 z 发生在表引用 t2 的引用范围之
外。在最内部的子查询中,仅可解析属于 t4、t3 或 t1 的列引用。表引用的作用
域通过子查询向下扩展,但不越过 UNION 运算符扩展到兄弟 SELECT 语句。
INTERSECT 运算符
当通过此集合运算符组合两个查询时,INTERSECT 计算通过为其运算对象的两
个查询返回的行的交集。
INTERSECT 返回的行展现在左边和右边的 SELECT 语句的结果集中。
INTERSECT 结果通常是不同的或唯一的行,因为 INTERSECT 消除任何重复的
行。
请考虑下列示例,其中表 t1 有下列行:
create table t1 (col1 int);
insert into t1 values (1);
insert into t1 values (2);
insert into t1 values (2);
insert into t1 values (2);
insert into t1 values (3);
insert into t1 values (4);
insert into t1 values (4);
insert into t1 values (NULL);
insert into t1 values (NULL);
insert into t1 values (NULL);
在同一示例中,表 t2 有这些行:
create table t2 (col1 int);
insert into t2 values (1);
insert into t2 values (3);
insert into t2 values (4);
insert into t2 values (4);
insert into t2 values (NULL);
下列查询从 INTERSECT 操作对象的左边与右边的两个查询返回不同的行。在此
要注意的重要问题是该结果有 NULL 值。因为当将表 t2 与表 t1 进行比较时,
考虑到表 t2 中的 NULL 值是相等的,因此来自该交集的 NULL 值返回在组合
的结果集中:

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 957
SELECT col1 FROM t1 INTERSECT SELECT col1 FROM t2;

col1
1
3
4
4 row(s) retrieved.
INTERSECT 运算符有一些(但不是所有)与 UNION 运算符相同的限制,但
INTERSECT 不支持使得 UNION 能够返回重复的值的 ALL 关键字。另请参阅
主题 对组合的 SELECT 的限制。
MINUS 运算符
当通过此集合运算符来组合两个查询时,MINUS 运算符计算通过左边的
SELECT 语句返回的行与通过右边的 SELECT 语句返回的行之间的差集。
MINUS 仅返回出现在第一个结果集但不在第二个集合中的那些行。MINUS 结果
通常是不同的或唯一的行,因为 MINUS 消除任何重复的行。
对于罗列在 INTERSECT 运算符 主题中的同一数据集,下列查询从 MINUS 运
算符左边的查询的结果集返回不在右边的查询的结果集中的所有不同的行:
SELECT col1 FROM t1 MINUS SELECT col1 FROM t2;

col1
2
1 row(s) retrieved.
MINUS 运算符有一些(但不是所有)与 UNION 运算符相同的限制,但 MINUS
不支持使得 UNION 能返回重复的值的 ALL 关键字。另请参阅主题 对组合的
SELECT 的限制。

要从两个或多个表中选择数据,在 FROM 子句中指定表名。添加 WHERE 子句一章每个
表中的至少一个相关列间创建连接条件。WHERE 子句创建临时组合表。在其中,满足连
接添加的每一对行都被链接以组成单个行。
简单连接根据每个表中某列的关系组合来自两个或多个表的信息。组合连接根据每个表中
两个或多个列之间的关系连接两个或多个表。
要创建连接,必须在每个表中至少一列之间指定称为连接条件的关系。因为要对列进行比
较,所以它们必须具有兼容的数据类型。当连接大型表时,对连接条件中的列进行索引会
提高性能。
数据类型在 GBase 8s SQL 参考指南和 GBase 8s 数据库设计和实现指南中描述。索引
在 GBase 8s 管理员指南中详细所讨论。

onconfig.std 值
OPT_GOAL -1

0 或 -1
生效
编辑 onconfig 文件并重启数据库服务器之后。
用法
OPT_GOAL 参数使您能指定下列查询的优化目标之一:
优化 FIRST ROWS
优化 ALL ROWS
值 0 设置优化目标为 FIRST_ROWS。值 -1 设置优化目标为 ALL_ROWS,这是缺省值。
当您设置优化目标为优化 FIRST ROWS 时,请指定您想要数据库服务器优化感知响应时间
的查询。换句话说,交互应用的用户感知的响应时间,就是花费在屏幕上显示数据的时间。
设置优化目标为 FIRST ROWS,配置数据库服务器来返回满足查询的前几行数据。
当您设置优化目标为优化 ALL ROWS 时,请指定您想要数据库服务器优化的查询执行时间
的总计。使 ALL ROWS 优化目标指导数据库服务器来尽快处理总计查询,不管将前几行数
据返回到应用需要花费多长时间。
您可用四种方法之一指定优化目标:
l 通过查询(SELECT 语句)
使用 ALL_ROWS 和 FIRST_ROWS 指令。

GBase 8s 管理员参考
南大通用数据技术股份有限公司 - 116 -

l 通过会话
使用 SET OPTIMIZATION 语句。
l 通过环境
设置 OPT_GOAL 环境变量。
l 通过数据库服务器
设置 OPT_GOAL 配置参数。
上述列表按优先的降序罗列设置这个目标的机制。要确定优化目标,数据库服务器按上述
顺序检查设置。以遇到的第一个设置来确定优化目标。例如,如果查询包括 ALL_ROWS 指
令,但 OPT_GOAL 配置参数设置为 FIRST_ROWS,则 数据库服务器按照查询指定的,优化
ALL_ROWS。