SQL學習精粹以內外鏈接以及where和on條件的區別

sql內外鏈接(重點)

在oracle的SQL語句經常使用的鏈接有內鏈接(inner join),外鏈接(outer join)等,內鏈接又包括等值鏈接,非等值鏈接,自鏈接;而外鏈接又分爲左鏈接和右鏈接全鏈接。其中默認的是內鏈接的等值鏈接。sql

     爲了方便咱們建立兩張最簡易的表A、B,具體的表結構參看下面,來分析內鏈接與外鏈接的區別oracle

圖1,表A          圖2 表B

                      圖1                                                                      圖2測試

 

兩個表要作鏈接,必需要有鏈接字段,而在表A和表B中鏈接字段是Aid和Bnamid,下圖說明了鏈接之間關係圖3spa

圖3

                                                                  圖3code

    (1) 內鏈接:利用內鏈接(等值)就可獲取藍色的公共部分C,即圖3中的數據集C,結果集爲以下:innodb

   

             圖4

                                                                   圖4table

 

   其實select * from A join B on A.Aid=B.Bnamid;等價於select * from A,B where A.Aid=B.Bnamid;
       注:非等值鏈接主要的話是針對一個範圍來查詢數據,自鏈接主要就是把1張表當作兩張表來用                        
   (2)外鏈接:分爲左外鏈接(left join)與右外鏈接(right join)
      
      左外鏈接即公共顯示的藍色部分C1+顯示黃色的記錄集A1,顯示語句等價於class

 select * from A,B where A.Aid=B.Bnamid(+);       效率

注:sql中(+),表示外鏈接 能夠省略 left/right join 。。and。。等關鍵字,其中(+)在等號左邊表示右外鏈接,在等號右邊表示左外鏈接。select

 

            圖5

                                                                    圖  5

 

右外鏈接即公共顯示的藍色部分C1+顯示綠色的B1,顯示語句等價於

select * from A,B where A.Aid(+)=B.Bnamid;

          圖6 

                                                                      圖6

 

  表A和表B狀況是相對的,以上實驗都是A在左邊的狀況,其實A left join B與B right join A的狀況的結果集是同樣的。

另外,全鏈接 full   join表示三個部分所有包含到結果集,彼此沒有與之匹配的數據行填充null。

鏈接條件子語句where和on的區別

測試表環境:

drop table if exists join_a;
create table  join_a(
f1 int not null comment '字段1',
f2 int not null comment '字段2'
)engine=innodb default charset=utf8 comment '鏈接測試A表';

insert into join_a(f1,f2) value(1,1);
insert into join_a(f1,f2) value(1,1);
insert into join_a(f1,f2) value(1,2);
insert into join_a(f1,f2) value(1,2);
insert into join_a(f1,f2) value(2,3);
insert into join_a(f1,f2) value(2,3);
insert into join_a(f1,f2) value(2,4);
insert into join_a(f1,f2) value(2,4);

drop table if exists join_b;
create table  join_b(
f1 int not null comment '字段1',
f2 int not null comment '字段2'
)engine=innodb default charset=utf8 comment '鏈接測試B表';

insert into join_b(f1,f2) value(1,5);
insert into join_b(f1,f2) value(1,5);
insert into join_b(f1,f2) value(1,6);
insert into join_b(f1,f2) value(1,6);
insert into join_b(f1,f2) value(2,7);
insert into join_b(f1,f2) value(2,7);
insert into join_b(f1,f2) value(2,8);
insert into join_b(f1,f2) value(2,8);

左外鏈接

左外鏈接(無條件):

select t1.* ,t2.* from join_a t1 left join join_b t2 on t1.f1=t2.f1;

運行結果:

+----+----+----+----+
| f1 | f2 | f1 | f2 |
+----+----+----+----+
|  1 |  1 |  1 |  5 |
|  1 |  1 |  1 |  5 |
|  1 |  2 |  1 |  5 |
|  1 |  2 |  1 |  5 |
|  1 |  1 |  1 |  5 |
|  1 |  1 |  1 |  5 |
|  1 |  2 |  1 |  5 |
|  1 |  2 |  1 |  5 |
|  1 |  1 |  1 |  6 |
|  1 |  1 |  1 |  6 |
|  1 |  2 |  1 |  6 |
|  1 |  2 |  1 |  6 |
|  1 |  1 |  1 |  6 |
|  1 |  1 |  1 |  6 |
|  1 |  2 |  1 |  6 |
|  1 |  2 |  1 |  6 |
|  2 |  3 |  2 |  7 |
|  2 |  3 |  2 |  7 |
|  2 |  4 |  2 |  7 |
|  2 |  4 |  2 |  7 |
|  2 |  3 |  2 |  7 |
|  2 |  3 |  2 |  7 |
|  2 |  4 |  2 |  7 |
|  2 |  4 |  2 |  7 |
|  2 |  3 |  2 |  8 |
|  2 |  3 |  2 |  8 |
|  2 |  4 |  2 |  8 |
|  2 |  4 |  2 |  8 |
|  2 |  3 |  2 |  8 |
|  2 |  3 |  2 |  8 |
|  2 |  4 |  2 |  8 |
|  2 |  4 |  2 |  8 |
+----+----+----+----+
32 rows in set

說明:取t1表的第一行,掃瞄t2表,按條件作對比,若是知足條件,就加入返回結果表.
            而後取t1表的第二行,掃瞄t2表,按條件作對比,若是知足條件,就加入返回結果表.

            。。。。。。。。。。。。。
           重複以上過程,直到t1表掃描結束。

左表條件(on+and條件):

select t1.* ,t2.* from join_a t1 left join join_b t2 on t1.f1=t2.f1 and t1.f2=1;

說明:給左表加條件的時候,左表知足條件的,按上面的過程返回值,左表不知足條件的,直接輸出,右表的列補null。

如下三種語句查詢結果同樣:

--左外鏈接(where條件),不完整的數據不顯示
select t1.* ,t2.* from join_a t1 left join join_b t2 on t1.f1=t2.f1 where t1.f2=1;
--內鏈接(on+and條件),不完整的數據不顯示
select t1.* ,t2.* from join_a t1 inner join join_b t2 on t1.f1=t2.f1 and t1.f2=1;
--使用where條件來鏈接表(and條件),不完整的數據不顯示
select t1.* ,t2.* from join_a t1 , join_b t2 where t1.f1=t2.f1 and t1.f2=1;

--其中後兩種效率更高

說明:若是有where子語句,先執行where後鏈接查詢,執行where的時候已經把不知足條件的直接去除,因此最後的結果沒有填充null的行。效果同inner join。

當外鏈接使用where條件語句的時候,能夠把left join(或者right join) 改成inner jin, 由於inner join比left join 要快!

右表條件(on+and條件):

select t1.* ,t2.* from join_a t1 left join join_b t2 on t1.f1=t2.f1 and t2.f2=5;

如下三種語句查詢結果同樣:

--on+where,不完整的數據不顯示
select t1.* ,t2.* from join_a t1 left join join_b t2 on t1.f1=t2.f1 where t2.f2=5;
--inner+on+and,不完整的數據不顯示
select t1.* ,t2.* from join_a t1 inner join join_b t2 on t1.f1=t2.f1 and t2.f2=5;
--where+and,不完整的數據不顯示
select t1.* ,t2.* from join_a t1 , join_b t2 where t1.f1=t2.f1 and t2.f2=5;

--其中後兩種效率更高
相關文章
相關標籤/搜索