前言:Sybase的左右连接运算符(*=,=*)提供了一种简洁的方式来实现LEFT JOIN,RIGHT JOIN语法,但在与筛选条件组合时,其行为比较令人费解。本文将深入探讨Sybase左连接运算符(*=)与筛选条件组合时的行为,并提供一些CP8项目中遇到的实际案例。对于右连接(=*)的分析,读者可自行研究。
在Sybase中,左连接运算符(*=)用于指定左连接。它保留了左侧表的所有行,即使右侧表中没有匹配的行。例如,以下查询将左侧表l的所有行与右侧表r中匹配的行结合起来:
SELECT l.*, r.* FROM l *= r
等价于:
SELECT l.*, r.* FROM l LEFT JOIN r ON (l.id=r.id)
其中表l和r的结构分别为:
create table r( id int, name varchar(8) )
create table l( id int, name varchar(8) )
插入以下测试数据,执行左连接后,结果如下图所示:
insert into l values( 1, 'aaa')
insert into l values( 2, 'bbb')
insert into l values( 3, 'ccc')
insert into r values( 1, 'AAA')
insert into r values( 2, 'bbb')
insert into r values( 4, 'DDD')
:Sybase左连接与筛选条件组合的深入解析/1707564944.png)
当左连接与筛选条件组合时,需要特别注意条件的放置,因为Sybase的行为与其他数据库系统不同。
考虑以下两个查询:
-- 查询1
SELECT l.*, r.* FROM l, r WHERE l.id *= r.id AND r.name='bbb'
-- 查询2
SELECT l.*, r.* FROM l LEFT JOIN r ON (l.id=r.id AND r.name='bbb')
这两个查询是等价的,含义是:左侧表l和右侧表r中name='bbb’对应的记录进行左连接。在这种情况下,左连接运算符(*=)与筛选条件r.name='bbb'可以合并在一个ON子句中。
查询1结果:
:Sybase左连接与筛选条件组合的深入解析/3499383950.png)
查询2结果(与查询1相同):
:Sybase左连接与筛选条件组合的深入解析/3875506390.png)
然而,以下查询与上述两个查询不等价:
-- 查询3
SELECT l.*, r.* FROM l LEFT JOIN r ON (l.id=r.id) WHERE r.name='bbb'
查询3首先执行左连接,然后应用筛选条件r.name='bbb'。查询3结果如下:
:Sybase左连接与筛选条件组合的深入解析/416584018.png)
Sybase中,筛选左侧表的行为与筛选右侧表行为完全不同,不能盲目照搬示例1的准则。
-- 查询4
SELECT l.*, r.* FROM l, r WHERE l.id *= r.id AND l.name='bbb'
-- 查询5
SELECT l.*, r.* FROM l LEFT JOIN r ON (l.id=r.id) WHERE l.name='bbb'
这两个查询是等价的。它们都表示左侧表l和右侧表r基于l.id=r.id进行左连接,并且最后过滤出l.name='bbb'的记录。在这种情况下,筛选条件l.name='bbb'可以在WHERE子句中单独使用。
查询4结果:
:Sybase左连接与筛选条件组合的深入解析/3059752943.png)
查询5结果(与查询4结果相同):
:Sybase左连接与筛选条件组合的深入解析/507740701.png)
然而,以下查询与上述两个查询不等价:
-- 查询6
SELECT l.*, r.* FROM l LEFT JOIN r ON (l.id=r.id and l.name='bbb')
查询6将l.name='bbb'作为左连接的一部分条件,这意味着只有当l.id与r.id相等且l.name的值为'bbb'时,l表中的行才会与r表中的行结合。查询6结果如下:
:Sybase左连接与筛选条件组合的深入解析/3326052665.png)
深入理解Sybase中左右连接运算符与筛选条件相结合的复杂行为,对于顺利且准确地将Sybase代码迁移至PG代码具有至关重要的作用。HA的Sybase存储过程大量使用左右连接,我们对其正确理解不仅能够显著提升代码的质量水平,还能极大增强开发工作的效率。