86標准sql與92標准SQL用法區別


在開發 Oracle 9i時, 數據庫還時間了ANSL SQL/92標准的鏈接語法, 在書中建議在使用Oracle 9i及更高版本時,應該使用SQL/92標准的語法;在使用Oracle 8i 及更低版本時,應該使用SQL/86標准的語法。 -----《Oracle Database 10g SQL 開發指南》


86標准sql是傳統的表連接寫法,就是直接將表寫在FROM后邊,將表連接條件與過濾條件都寫在WHERE后邊。
92標准SQL是采用JOIN的表連接方法。分為LEFT JOIN,RIGHT JOIN,INNER JOIN,每一種JOIN方法都可以使用86版SQL轉化得到相應寫法,但並不是完全相同。

下面舉例說下兩種表連接的用法:
測試數據:
create table a (id integer,name varchar(20));
create table b (id integer,name varchar(20));
create table c (id integer,name varchar(20));

insert into a values(1,'a1');
insert into a values(2,'a2');
insert into a values(3,'a3');
insert into a values(4,'a4');
insert into a values(5,'a5');

insert into b values(2,'b2');
insert into b values(3,'b3');
insert into b values(4,'b4');
insert into b values(5,'b5');
insert into b values(6,'b6');

insert into c values(1,'c1');
insert into c values(2,'c2');
insert into c values(3,'c3');
insert into c values(4,'c4');

1: 等值連接 INNER JOIN
SQL> select a.id,a.name,b.id,b.name,c.id,c.name
2 from a inner join b on a.id=b.id
3 inner join c on a.id=c.id ;
ID NAME ID NAME ID NAME
--------- -------------------- ---------- -------------------- ---------- ----
2 a2 2 b2 2 c2
3 a3 3 b3 3 c3
4 a4 4 b4 4 c4

以上92版SQL 與以下86版SQL結果相似;
select a.id,a.name,b.id,b.name,c.id,c.name
from a ,b ,c
where a.id=b.id
and a.id=c.id

2:左連接 left join


先看92兩種寫法得到的結果對比一下。
SQL> select a.id,a.name,b.id,b.name,c.id,c.name
2 from a left join b on a.id=b.id
3 left join c on b.id=c.id ;

ID NAME ID NAME ID NAME
---------- -------------------- ---------- -------------------- ---------- -----
---------------
2 a2 2 b2 2 c2
3 a3 3 b3 3 c3
4 a4 4 b4 4 c4
1 a1
5 a5 5 b5
SQL> select a.id,a.name,b.id,b.name,c.id,c.name
2 from a left join b on a.id=b.id
3 left join c on a.id=c.id ;

ID NAME ID NAME ID NAME
---------- -------------------- ---------- -------------------- ---------- -----
---------------
2 a2 2 b2 2 c2
3 a3 3 b3 3 c3
4 a4 4 b4 4 c4
5 a5 5 b5
1 a1 1 c1
兩種寫法都是左連接,唯一不同的就是與表C進行連接時的連接條件不同。但得到的結果卻完全不同。
在處理C表時,數據庫判定左接連基准表的依據是ON 后邊的連接條件。對於第一個SQL(b.id=c.id),C表是和處理過的B表的結果集進行
連接,從B表得到結果集中ID取值為2,3,4,5 。以此為結果為基准再與C表進行連接,因此,從C表中得到的符合條件數據的ID為2,3,4
對於第二個SQL,C表是和A表進行連接,因為自始至終A表都是左連接中的基准表,所以表中的數據量不變,C表再與之進行左連接時得到的結果集中的ID為1,2

,3,4

對於以上兩種SQL的寫法,分別可以用以下寫法代替
第一條SQL:
select a.id,a.name,b.id,b.name,c.id,c.name
from a ,b ,c
where a.id=b.id(+)
and b.id=c.id(+)
第二條SQL
select a.id,a.name,b.id,b.name,c.id,c.name
from a ,b ,c
where a.id=b.id(+)--b表和a表進行左連接,以a表為准,稱為左連接。注意哦,(+)是放在右邊的
and a.id=c.id(+)--c表和a表進行左連接,以a表為准
3:右連接
92版SQL寫時,只需將LEFT換成RIGHT就可以了。 86版SQL,只需改變下(+)的位置不可以了。

4:92版sql中的where條件與ON條件
86版中的連接條件與過濾條件都放在WHERE條件后邊了。
但92版SQL中,連接條件放在ON 后邊,過濾條件放在WHERE 后邊。
注意區分,以下兩個SQL得到的結果是不同的:
SQL> select a.id,a.name,b.id,b.name
2 from a left join b on a.id=b.id
3 and b.id>2 ;

ID NAME ID NAME
---------- -------------------- ---------- ----------
3 a3 3 b3
4 a4 4 b4
5 a5 5 b5
1 a1
2 a2

SQL> select a.id,a.name,b.id,b.name
2 from a left join b on a.id=b.id
3 where b.id>2 ;

ID NAME ID NAME
---------- -------------------- ---------- -----
3 a3 3 b3
4 a4 4 b4
5 a5 5 b5
雖然是相同的條件,但 放的位置不同,得到的結果不同。
對於第一個SQL。 b.id>2 是在進行表連接的時候對B表的數據進行過濾。
但對於第二個SQL, b.id>2 是對結果集進行過濾。

以上兩種SQL的寫法對應到86版SQL時的寫法是:
select a.id,a.name,b.id,b.name
from a ,b
where a.id=b.id(+)
and b.id>2
它是與第二個SQL的結果保持一至的(這個地方一直懷疑,應該是數據庫根據不同情況來應用b.id>2為驅動條件還是過濾條件,試驗了發多數據,都沒有得到是把 b.id>2當作驅動條件來使用的,都是當成過濾條件)。

原文地址:

http://hi.baidu.com/420350501/blog/item/dd5344f15d010c3cbd3109fc.html

http://www.itpub.net/thread-919997-1-1.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM