Oracle關於left join on…and 及 left join on...whe...

 關於left join...on...and...以及left join...on...where的區別,網上不少的說法是對於left join...on...and...,and所限定的條件只對關聯字段起做用,好比select a.* from tmp_table_a a left join tmp_table_b b on a.col1=b.col1 and b.col2=xx,不少人認爲條件b.col2=xx是不起做用的。 測試

  對於這種說法,我我的是不認同的,至少來說,這是一種不負責任的說法。如下是個人一些測試例子,從這裏你們就能夠理解這兩個用法的區別。 spa

select count(*) from tb_bo_valusr_new where month=201010 and brand=3;--141858
select count(*) from tb_bo_valusr_new where month=201010;---2281189
select count(distinct usr_nbr) from tb_bo_valusr_new where brand=3;--152110
select count(distinct usr_nbr) from tb_bo_valusr_new where month=201010;--2281189
select count(*) from tb_bo_valusr_new;--4602747
select count(*) from tmp_msy_bj_001;--986843
select count(*) from tmp_msy_bj_001 where if_wlg='是';--272623
table

--例1
create table tmp_msy_bj_007
as select
a.usr_nbr,b.cmcc_branch_cd from
tmp_msy_bj_001 a
left join tb_bo_valusr_new b on a.usr_nbr=b.usr_nbr;
select count(*) from tmp_msy_bj_007;--1957872
select count(distinct usr_nbr) from tmp_msy_bj_007;---986843
select count(*) from (select distinct * from tmp_msy_bj_007);--1024792
select

--例2 tab

create table tmp_msy_bj_008
as select
a.usr_nbr,b.cmcc_branch_cd from
tmp_msy_bj_001 a
left join tb_bo_valusr_new b on a.usr_nbr=b.usr_nbr and b.month=201010;
select count(*) from tmp_msy_bj_008;--986843
select count(distinct usr_nbr) from tmp_msy_bj_008;--986843
select count(*) from (select distinct * from tmp_msy_bj_008);--986843
di

--例3 時間

create table tmp_msy_bj_006
as select
a.usr_nbr,b.cmcc_branch_cd from
tmp_msy_bj_001 a
left join tb_bo_valusr_new b on a.usr_nbr=b.usr_nbr and b.month=201010
where a.if_wlg='是';
select count(*) from tmp_msy_bj_006;--272623
select count(distinct usr_nbr) from tmp_msy_bj_006;--272623
select count(*) from (select distinct * from tmp_msy_bj_006);--272623
co

--例4 join

create table tmp_msy_bj_005
as select
a.usr_nbr,b.cmcc_branch_cd from
tmp_msy_bj_001 a
left join tb_bo_valusr_new b on a.usr_nbr=b.usr_nbr and b.month=201010 and b.brand=3;
select count(*) from tmp_msy_bj_005;--986843
select count(distinct usr_nbr) from tmp_msy_bj_005;--986843
select count(*) from(select distinct * from tmp_msy_bj_005);--986843
new

--例5

create table tmp_msy_bj_003
as select
a.usr_nbr,b.cmcc_branch_cd,b.brand from
tmp_msy_bj_001 a
left join tb_bo_valusr_new b on a.usr_nbr=b.usr_nbr and b.brand=3;
select count(*) from tmp_msy_bj_003;--1062507
select count(distinct usr_nbr) from tmp_msy_bj_003;--986843
select count(*) from (select distinct * from tmp_msy_bj_003);--991560
select count(*) from tmp_msy_bj_003 where brand=3;--154124
select count(distinct usr_nbr) from tmp_msy_bj_003 where brand=3;--78460
select count(*) from tmp_msy_bj_003 where brand is null;--908383

--例6

create table tmp_msy_bj_002
as select
a.usr_nbr,b.cmcc_branch_cd from
tmp_msy_bj_001 a
left join tb_bo_valusr_new b on a.usr_nbr=b.usr_nbr where b.brand=3;
select count(*) from tmp_msy_bj_002;---154124
select count(distinct usr_nbr) from tmp_msy_bj_002;--78460
select count(*) from(select distinct * from tmp_msy_bj_002);--83177

--例7

create table tmp_msy_bj_011
as select
a.usr_nbr,b.cmcc_branch_cd from
tmp_msy_bj_001 a,tb_bo_valusr_new b where a.usr_nbr=b.usr_nbr and b.brand=3;
select count(*) from tmp_msy_bj_011;---154124
select count(distinct usr_nbr) from tmp_msy_bj_011;--78460
select count(*) from(select distinct * from tmp_msy_bj_011);--83177

--例8

create table tmp_msy_bj_009
as select
a.usr_nbr,b.cmcc_branch_cd from
tmp_msy_bj_001 a
left join tb_bo_valusr_new b on a.usr_nbr=b.usr_nbr where b.brand=3 and b.month=201010;
select count(*) from tmp_msy_bj_009;---78421
select count(distinct usr_nbr) from tmp_msy_bj_009;--78421
select count(*) from(select distinct * from tmp_msy_bj_009);--78421
--以上各個表的建立時間都在20秒內完成

--例9

create table tmp_msy_bj_004
as select
a.usr_nbr,b.cmcc_branch_cd from
tmp_msy_bj_001 a
left join tb_bo_valusr_new b on a.usr_nbr=b.usr_nbr and a.if_wlg='是';
--運行25分鐘都尚未結果

在以上本例子中,b表tb_bo_valusr_new表中每月都包含當月全量號碼,且單月號碼是沒重複的,而a 表tmp_msy_bj_001沒有重複記錄。在這樣的例子中,若是在left join 以後用 where 指定 b的非鏈接字段的限制條件,已至關於將A與B等值鏈接了,很明顯,這時的left join已失去意義,left join的本義是保留前面表的全部記錄,所以說將後一表中非鏈接字段的限制條件放在where以後是一種愚蠢的作法。而從上面的例5還能夠看出,在left join 後指定and b.column=....起的效果是:將a中符合b條件的記錄鏈接,並保留a中其它不符合的記錄一次。所以能夠這麼理解left join ...on...and...:能夠保證保留前面表的所有記錄,並可取到後面表中符合指定條件的記錄。而出現後面表的and...條件不起做用的狀況是:後一表即b表的記錄集是a表的一個子集。

 再從例9中看出,絕對不要把a的限制條件放在left join on...and...指定,那是找死。

相關文章
相關標籤/搜索