日期:2014-05-16  浏览次数:20776 次

外连接 及 无用的外连接
一:左右连接实例。

表TEST1:  id
         20
         30
         200
表TEST2:  id
         20
         30
         100
表TEST3:  id
         20
         100
         200

以下语句的查询结果
select t1.id as t1Id, t2.id as t2ID, t3.id as t3ID  from test1 t1 left join test2 t2 on t1.id = t2.id right join test3 t3 on t1.id = t3.id


结果: t1ID  t2ID  t3ID
      20    20     20
      200   null   200
      null  null   100

对于A left join B,则是A必有,B不必有。
对于A right join B,则是A不必有,B必有。

连续的连接时,A left join B right join C
则按照先后,先是A B的左连接,连接完之后再和C右连接。
A B的左连接,以A的记录为基准,
结果: t1ID  t2ID 
      20    20   
      30    30  
      200   null 

此结果再和C右连接,以C中全部记录为基准,
结果: t1ID  t2ID  t3ID
      20    20     20
      null  null   100
      200   null   200


二:无用的,多余的连接会影响效率
详见下例。
因为要确定的只是一个tin,那么就没必要用包含tin的主表再去 左外连接其余的表。
无论左外连接的表是否有符合条件的记录,主表的记录都是要包含进去的。


According to report, the following SQL is the slowest one.
     
SELECT DISTINCT cr01_trade_name, cg03_dereg_reason ......
from TR01_TAXPAYER_TIN t
where t.CR01_TIN_ID in
(SELECT a.CR01_TIN_ID
FROM TR12_ACCOUNTS_TIN a
left join TR02_OUTLET_TIN d on a.cr01_tin_id = d.cr01_tin_id and a.cr02_outlet_code = d.cr02_outlet_code
left join TR04_OUTLET_ADDRESS_TINS tr04 on a.cr01_tin_id = tr04.cr01_tin_id
left join TR37_ECONOMIC_CATEGORY_TIN tr37 on tr37.cr01_tin_id = a.cr01_tin_id
right join
(select e.CR01_TIN_ID, ......
from TR01_TAXPAYER_TIN e, TG09_TAXPAYER_TYPES c
where e.cg09_taxpayer_type=c.cg09_taxpayer_type) b on a.cr01_tin_id = b.cr01_tin_id
where 1=1 AND b.CS05_OFFICE_ID=111)
ORDER BY t.CR01_TIN_ID;

可以用下边的替换。即将在这里无用的左外连接去掉

SELECT DISTINCT t.cr01_trade_name,t.cg03_dereg_reason,....
from TR01_TAXPAYER_TIN t,TG09_TAXPAYER_TYPES c
where t.cg09_taxpayer_type=c.cg09_taxpayer_type and
t.CS05_OFFICE_ID=111 and
exists(select 1 from TR12_ACCOUNTS_TIN a where t.CR01_TIN_ID=a.CR01_TIN_ID)
order by t.CR01_TIN_ID;

The SQL Elapsed time can reduce from 00:00:01.53 to 00:00:00.30.