上周我惊讶地发现 sybase 12 不支持完全外连接。但我突然想到,完全外连接应该与左外连接与同一 sql 的右外连接联合起来相同。谁能想到这不成立的原因?
4 回答
UNION ALL
左连接与右连接,但将右连接限制为仅在基表中不存在的行(如果它们存在,则在表中它们不会为空时,在连接上返回空)。
对于此代码,您需要创建两个表 t1 和 t2。t1 应该有一个名为 c1 的列,其中五行包含值 1-5。t2 还应该有一个 c1 列,其中包含值 2-6 的五行。
全外连接:
select * from t1 full outer join t2 on t1.c1=t2.c1 order by 1, 2;
全外连接等价物:
select t1.c1, t2.c1 from t1 left join t2 on t1.c1=t2.c1
union all
select t1.c1, t2.c1 from t1 right join t2 on t1.c1=t2.c1
where t1.c1 is null
order by 1, 2;
请注意右侧连接选择上的 where 子句将结果限制为仅不重复的结果。
UNION
-ing 两个OUTER JOIN
语句应该导致重复的行代表您从INNER JOIN
. 您可能必须SELECT DISTINCT
对UNION
. 一般来说,如果你必须使用 aSELECT DISTINCT
这意味着它不是一个精心设计的查询(或者我听说过)。
如果将它们与 结合UNION ALL
,您将得到重复项。如果只使用UNION
不带ALL
,它将过滤重复项,因此相当于完全连接,但查询也将更加昂贵,因为它必须执行不同的排序。
首先,我不知道你为什么使用 12.x。在 2007 年 4 月 3 日收到通知后,它于2009 年 12 月 31 日结束。2009年 1 月发布了 15.0.2(第一个实体版本)。15.5 更好,并于 2009 年 12 月 2 日可用,因此您是两个主要版本,并且至少 13 个月,过期。
ASE 12.5.4 具有新的 Join 语法。(你没有指定,你可能在 12.5.0.3,之前的版本)。
DB2 和 Sybase 没有实现
FULL OUTER JOIN
,这正是您确定的原因:它被LEFT ... UNION ... RIGHT
without覆盖ALL
。这不是“不支持”FOJ 的情况;这是缺少关键字的情况。然后你会遇到一个问题,即 Sybase 和 DB2 类型通常永远不会使用外连接,更不用说 FOJ,因为它们的数据库往往更加规范化,等等。
最后,您可以在提供 FOJ 功能的任何版本的 Sybase 中使用完全普通的 SQL,并且在 12.x 上明显更快;仅在 15.x 上稍微快一点。它有点像 RANK() 函数:如果您可以编写子查询,则完全没有必要。
它不需要的第二个原因
FULL OUTER
,就像一些低端引擎所做的那样,是因为新的优化器非常快,并且查询是完全规范化的。IE。它一次执行 LEFT 和 RIGHT。根据您的 SARG 和 DataType 不匹配等,它可能仍然需要排序合并,但这也是在所有三个级别上进行流式传输的:磁盘 I/O 子系统;引擎); 和网络处理程序。如果您的表是分区的,那么它会在该级别额外并行化。
如果您的服务器没有配置并且您的结果集非常大,您可能需要增加
proc cache size
和number of sort buffers
. 就这样。