LEFT SEMI JOIN:左半開連接會返回左邊表的記錄,前提是其記錄對於右邊表滿足ON語句中的判定條件。對於常見的內連接(INNER JOIN),這是一個特殊的,優化了的情況。大多數的SQL方言會通過in.......exists結構來處理這種情況。
准備表:
create table dcx1107(
id bigint
);
insert into dcx1107 values(-1);
insert into dcx1107 values(1);
create table dcx_2(
id bigint
,role string
);
insert into dcx_2 values(-1,'C1');
insert into dcx_2 values(1,'C1');
insert into dcx_2 values(1,'C2');
查詢數據:
--join的select的結果中可以有t1(左表),t2(右表)兩張表的字段
select
t1.id,t2.role
from dcx1107 t1
join dcx_2 t2
on t1.id=t2.id;
結果:
--left semi join的select的結果中只允許出現t1(左表)表的字段
select
t1.id
from dcx1107 t1
left semi join dcx_2 t2
on (t1.id=t2.id);
--等價於
select
t1.id
from dcx1107 t1
where id in (select id from dcx_2)
;
--等價於
select
t1.id
from dcx1107 t1
where EXISTS (select 1 from dcx_2 t2 where t1.id=t2.id)
結果:
這樣寫會報錯
select
t1.id,t2.role
from dcx1107 t1
left semi join dcx_2 t2
on (t1.id=t2.id);
總結:
對待右表中重復key的處理方式差異:因為 left semi join 是 in(keySet) 的關系,遇到右表重復記錄,左表會跳過,而 join on 則會一直遍歷。
left semi join 中最后 select 的結果只許出現左表,因為右表只有 join key 參與關聯計算了,而 join on 默認是整個關系模型都參與計算了。