返回首页

gbase数据、南大通用产品文档:GBase8a

更新日期:2024年09月11日

监控平台日志管理................................ 111

本章显示如何在 SELECT 语句中创建和使用外部连接。
创建连接讨论内部连接。
尽管内连
接同等看待两个或多个连接的表,但外连接不同等看待两个或多个连接的表。外连接使其
中一个表成为控制表(也称为外部表),控制其他从属表(也称为内部表)。
在内连接或简单连接中,结果只包含满足连接条件的行组合。废弃不满足连接条件的行。
在外连接中,结果包含满足连接条件的行与控制表中的行(如果在从属表中找不到匹配的
行那么将废弃这些行)的组合。在从属表中无匹配行控制表的行在选自从属表的列中包括
NULL 值。
外连接允许您在应用连接条件之前将连接过滤器应用于内部表。
数据库服务器的较早版本只支持对用于外连接的 ANSI-SQL 标准语法的 GBase 8s 扩展。
此语法仍受支持。然而,ANSI-SQL 标准语法在创建查询方面灵活性更高。建议使用
ANSI-SQL 标准语法来创建新查询。不管您使用何种形式的语法,必须将它用于单个查询
块中的所有外连接。
在依赖于外连接之前,确定一个或多个内连接是否可工作。当不需要来自其它表的补充信
息时,通常可以使用内连接。
限制: 不能在同一查询块中组合 GBase 8s 和 ANSI 外连接语法。
有关外连接的语法的信息,请参阅《GBase 8s SQL 指南:语法》。


GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 123 -

对外连接语法的 GBase 8s 扩展
对外连接语法的 GBase 8s 扩展在外连接的开始处使用 OUTER 关键字。当使用 GBase
8s 语法时,必须在 WHERE 子句中包含连接条件。在将 GBase 8s 语法用于外连接时,数
据库服务器支持以下三种基本类型的外连接:

对两个表的外连接

与第三个表进行简单连接的外连接

将两个表与第三个表进行外连接
外连接必须具有 Projection 子句、FROM 子句和 WHERE 子句。连接条件在 WHERE 子
句中表述。要将简单连接转换为外连接,在 FROM 子句中从属表的名称前面之间插入关
键字 OUTER 。如在本节中后面所示,可以在查询中多次包括 OUTER 关键字。
没有对外连接语法的 GBase 8s 扩展等价于 ANSI 右外连接。

ANSI 连接语法
以下 ANSI 连接受支持:

左外连接

右外连接
ANSI 外连接语法用 LEFT JOIN 、
LEFT OUTER JOIN 、
RIGHT JOIN 或 RIGHT OUTER
JOIN 关键字开始外连接。OUTER 关键字是可选的。查询可在 ON 子句中指定连接条件
和可选连接过滤器。WHERE 子句指定后连接(post-join)过滤器。另外,可以使用 LEFT
或 right 子句显式指定连接的类型。
当用左括号开始连接时,
ANSI 连接语法还允许外连接
的控制部分或从属部分作为另一个连接的结果集。
如果将 ANSI 语法用于外连接,那么必须将 ANSI 语法用于单个查询块中的所有外连接。

提示: 为了简介起见,本节中的示例使用表别名。别名讨论表别名。

左外连接
在左外连接的语法中,外连接的控制表显示在开始外连接的关键字左边。左外连接返回连
接条件为 true 的所有行,除此之外,还返回控制表中的所有其它行并将从属表中的相应值
显示为 NULL。
下列查询使用 ANSI 语法 LEFT OUTER JOIN 来获取与图 1(它使用 GBase 8s 外连接语
法)相同的结果:
图: 查询
SELECT c.customer_num, c.lname, c.company, c.phone,
u.call_dtime, u.call_descr

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 124 -

FROM customer c LEFT OUTER JOIN cust_calls u
ON c.customer_num = u.customer_num;
在此示例中,可以使用 ON 子句来指定连接条件。可以在 WHERE 子句中添加其它过滤
器来限制结果集;此类过滤器是后连接(post-join)过滤器。
以下查询只返回客户没有致电客户服务中心的行。在此查询中,数据库服务器
对 customer 和 cust_calls 表的 customer_num 列执行外连接之后在 WHERE 子句中应用过
滤器。
图: 查询
SELECT c.customer_num, c.lname, c.company, c.phone,
u.call_dtime, u.call_descr
FROM customer c LEFT OUTER JOIN cust_calls u
ON c.customer_num = u.customer_num
WHERE u.customer_num IS NULL;
除了前面的示例之外,下列示例显示了可与 ANSI 连接语法配合使用的各种查询构造类
型:
SELECT *
FROM (t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t3.c1) JOIN (t4 LEFT OUTER JOIN t5 ON t4.c1=t5.c1)
ON t1.c1=t4.c1;

SELECT *
FROM (t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t3.c1),
(t4 LEFT OUTER JOIN t5 ON t4.c1=t5.c1)
WHERE t1.c1 = t4.c1;

SELECT *
FROM (t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t3.c1) LEFT OUTER JOIN (t4 JOIN t5 ON t4.c1=t5.c1)
ON t1.c1=t4.c1;

SELECT *
FROM t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t2.c1;

SELECT *

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 125 -

FROM t1 LEFT OUTER JOIN (t2 LEFT OUTER JOIN t3 ON t2.c1=t3.c1)
ON t1.c1=t3.c1;

SELECT *
FROM (t1 LEFT OUTER JOIN t2 ON t1.c1=t2.c1)
LEFT OUTER JOIN t3 ON t2.c1=t3.c1;

SELECT *
FROM (t1 LEFT OUTER JOIN t2 ON t1.c1=t2.c1)
LEFT OUTER JOIN t3 ON t1.c1=t3.c1;

SELECT *
FROM t9, (t1 LEFT JOIN t2 ON t1.c1=t2.c1),
(t3 LEFT JOIN t4 ON t3.c1=10), t10, t11,
(t12 LEFT JOIN t14 ON t12.c1=100);

SELECT * FROM
((SELECT c1,c2 FROM t3) AS vt3(v31,v32)
LEFT OUTER JOIN
( (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);
上面最后一个示例说明了关于派生表的连接。它指定将外查询的 FROM 子句中子查询的
结果和另一个其它两个子查询结果的左外连接的结果进行左外连接。请参阅FROM 子句中
的子查询获得较为简单的符合 ANSI 语法的子查询示例。

右外连接
在右外连接的语法中,外连接的控制表显示在开始外连接的关键字右边。右外连接返回连
接条件为 true 的所有行,除此之外,还返回控制表中的所有其它行并将从属表中的相应值
显示为 NULL。
下列查询是对 customer 和 orders 表上的右外连接的一个示例。
图: 查询
SELECT c.customer_num, c.fname, c.lname, o.order_num,

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 126 -

o.order_date, o.customer_num
FROM customer c RIGHT OUTER JOIN orders o
ON (c.customer_num = o.customer_num);
该查询返回控制表 orders 中的所有行,并且在必要时,将从属表 customer 中的相应值显示
为 NULL。
图: 查询结果
customer_num fname lname order_num order_date customer_num
104 Anthony Wiggins 1001 05/30/1998 104
101 Ludwig Pauli 1002 05/30/1998 101
104 Anthony Wiggins 1003 05/30/1998 104
1004 06/05/1998 106

简单连接
以下查询是 customer 和 cust_calls 表上简单连接的示例。
图: 查询
SELECT c.customer_num, c.lname, c.company,
c.phone, u.call_dtime, u.call_descr
FROM customer c, cust_calls u
WHERE c.customer_num = u.customer_num;
该查询只返回客户已致电客户服务中心的那些行,如下所示。
图: 查询结果
customer_num 106
lname Watson
company Watson & Son
phone 415-389-8789
call_dtime 1998-06-12 08:20
call_descr Order was received, but two of the cans of
ANZ tennis balls within the case were empty

customer_num 116
lname Parmelee
company Olympic City
phone 415-534-8822
call_dtime 1997-12-21 11:24
call_descr Second complaint from this customer! Received

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 127 -

two cases right-handed outfielder gloves (1 HRO)
instead of one case lefties.

对两个表的简单外连接
下列查询使用与前面示例相同的 Projection 子句、表和比较条件,但这一次它用 GBase
8s 扩展语法创建简单外连接。
图: 查询
SELECT c.customer_num, c.lname, c.company,
c.phone, u.call_dtime, u.call_descr
FROM customer c, OUTER cust_calls u
WHERE c.customer_num = u.customer_num;
cust_calls 表前面的附加关键字 OUTER 使该表成为从属表。
外连接导致查询返回有关所有
客户的信,而不管它们是否已致电客户服务中心。检索控制表 customer 的所有行,并且将
NULL 值指定给从属表 cust_calls 的列,如下所示。
图: 查询结果
customer_num 101
lname Pauli
company All Sports Supplies
phone 408-789-8075
call_dtime
call_descr

customer_num 102
lname Sadler
company Sports Spot
phone 415-822-1289
call_dtime
call_descr

customer_num 107
lname Ream
company Athletic Supplies
phone 415-356-9876
call_dtime
call_descr

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 128 -


customer_num 108
lname Quinn
company Quinn's Sports
phone 415-544-8729
call_dtime
call_descr

与第三个表进行简单连接的外连接
使用 GBase 8s 语法,下列查询显示作为第三个表的简单连接结果的外连接。这第二种类型
的外连接也称为嵌套简单连接。
图: 查询
SELECT c.customer_num, c.lname, o.order_num,
i.stock_num, i.manu_code, i.quantity
FROM customer c, OUTER (orders o, items i)
WHERE c.customer_num = o.customer_num
AND o.order_num = i.order_num
AND manu_code IN ('KAR', 'SHM')
ORDER BY lname;
该查询首先对 orders 和 items 表执行简单连接,并检索 manu_code 为 KAR 或 SHM 的商
品的所有订单的信息。然后,它执行外连接以将此消息与控制 customer 表的数据结合。可
选的 ORDER BY 子句将数据重组为以下格式。
图: 查询结果
customer_num lname order_num stock_num manu_code quantity

114 Albertson
118 Baxter
113 Beatty

105 Vector
121 Wallack 1018 302 KAR 3
106 Watson

将两个表与第三个表相连接

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 129 -

使用 GBase 8s 扩展语法,下列查询显示作为两个表分别与第三个表的外连接结果的外连
接。在此第三种类型的外连接中,连接关系可能仅仅是控制表与从属表之间的关系。
图: 查询
SELECT c.customer_num, c.lname, o.order_num,
order_date, call_dtime
FROM customer c, OUTER orders o, OUTER cust_calls x
WHERE c.customer_num = o.customer_num
AND c.customer_num = x.customer_num
ORDER BY lname
INTO TEMP service;
该查询分别将从属表 orders 和 cust_calls 连接至控制表 customer;它不连接两个从属表。
INTO TEMP 子句将结果选择至临时表以供进一步处理或查询,如下所示。
图: 查询结果
customer_num lname order_num order_date call_dtime

114 Albertson
118 Baxter
113 Beatty
103 Currie
115 Grant 1010 06/17/1998

117 Sipes 1012 06/18/1998
105 Vector
121 Wallack 1018 07/10/1998 1998-07-10 14:05
106 Watson 1004 05/22/1998 1998-06-12 08:20
106 Watson 1014 06/25/1998 1998-06-12 08:20
如果图 1尝试在两个从属表 o 和 x 之间创建连接条件(如下所示),一条错误消息将指示
创建两侧外连接。
图: 查询
WHERE o.customer_num = x.customer_num

组合外连接的连接
要实现多级嵌套,可以创建使用三种外连接类型的任何组合的连接。使用 ANSI 语法,以
下查询创建了作为对两个表与另一个外连接的简单外连接组合结果的连接。
图: 查询

GBase 8s SQL 指南:教程
南大通用数据技术股份有限公司 - 130 -

SELECT c.customer_num, c.lname, o.order_num,
stock_num, manu_code, quantity
FROM customer c, OUTER (orders o, OUTER items i)
WHERE c.customer_num = o.customer_num
AND o.order_num = i.order_num
AND manu_code IN ('KAR', 'SHM')
ORDER BY lname;
该查询首先执行 orders 和 items 表上的外连接,并检索有关 manu_code 为 KAR 或 SHM
的商品的所有订单的信息。然后,它执行组合此信息与控制表 customer 的数据的另一个外
连接。
图: 查询结果
customer_num lname order_num stock_num manu_code quantity

114 Albertson
118 Baxter
113 Beatty
103 Currie
115 Grant 1010

117 Sipes 1012
117 Sipes 1007
105 Vector
121 Wallack 1018 302 KAR 3
106 Watson 1014
106 Watson 1004
当将外连接应用于某外连接与第三个表的结果时可用两种方法指定连接查询。两个从属表
已连接,但如果控制表和从属表共享公共列,那么可以将控制表连接至任一从属表而不影
响结果。

GBase 8c 提供两种方式返回数据:RETURN 或RETURN NEXT 及RETURN QUERY。
其中,RETURN NEXT 和RETURN QUERY 只适用于函数,不适用存储过程。