數(shù)據(jù)表t1 數(shù)據(jù)表t2
I1 C1 I2 C2
1
2
3 A
C 2
3
4 C
A
先找兩個表內(nèi)都存在的數(shù)據(jù)
select i1 from t1 where exists(select * from t2 where t1.i1=t2.i2);
再找t1表內(nèi)存在,t2表內(nèi)不存在的數(shù)據(jù)
select i1 form t1 where not exists(select * from t2 where t1.i1=t2.i2);
需要注意:在這兩種形式的子選擇里,內(nèi)層查詢中的星號代表的是外層查詢的輸出結(jié)果。內(nèi)層查詢沒有必要列出有關(guān)數(shù)據(jù)列的名字,田為內(nèi)層查詢關(guān)心的是外層查詢的結(jié)果有多少行。希望大家能夠理解這一點(diǎn)
? in 和not in 子選擇
在這種子選擇里面,內(nèi)層查詢語句應(yīng)該僅僅返回一個數(shù)據(jù)列,這個數(shù)據(jù)列里的值將由外層查詢語句中的比較操作來進(jìn)行求值。還是以上題為例
先找兩個表內(nèi)都存在的數(shù)據(jù)
select i1 from t1 where i1 in (select i2 from t2);
再找t1表內(nèi)存在,t2表內(nèi)不存在的數(shù)據(jù)
select i1 form t1 where i1 not in (select i2 from t2);
好象這種語句更容易讓人理解,再來個例子
比如你想找到所有居住在A和B的學(xué)生。
select * from student where state in('A','B')
二, 把子選擇查詢改寫為關(guān)聯(lián)查詢的方法。
1,匹配型子選擇查詢的改寫
下例從score數(shù)據(jù)表里面把學(xué)生們在考試事件(T)中的成績(不包括測驗(yàn)成績?。┎樵兂鰜怼?br />
Select * from score where event_id in (select event_id from event where type='T');
可見,內(nèi)層查詢找出所有的考試事件,外層查詢再利用這些考試事件搞到學(xué)生們的成績。
這個子查詢可以被改寫為一個簡單的關(guān)聯(lián)查詢:
Select score.* from score, event where score.event_id=event.event_id and event.event_id='T';
下例可以用來找出所有女學(xué)生的成績。
Select * from score where student_id in (select student_id form student where sex = 'f');
可以把它轉(zhuǎn)換成一個如下所示的關(guān)聯(lián)查詢:
Select * from score
Where student _id =student.student_id and student.sex ='f';
把匹配型子選擇查詢改寫為一個關(guān)聯(lián)查詢是有規(guī)律可循的。下面這種形式的子選擇查詢:
Select * from tablel
Where column1 in (select column2a from table2 where column2b = value);
可以轉(zhuǎn)換為一個如下所示的關(guān)聯(lián)查詢:
Select tablel. * from tablel,table2
Where table.column1 = table2.column2a and table2.column2b = value;
(2)非匹配(即缺失)型子選擇查詢的改寫
子選擇查詢的另一種常見用途是查找在某個數(shù)據(jù)表里有、但在另一個數(shù)據(jù)表里卻沒有的東西。正如前面看到的那樣,這種"在某個數(shù)據(jù)表里有、在另一個數(shù)據(jù)表里沒有"的說法通常都暗示著可以用一個left join 來解決這個問題。請看下面這個子選擇查詢,它可以把沒有出現(xiàn)在absence數(shù)據(jù)表里的學(xué)生(也就是那些從未缺過勤的學(xué)生)給查出來:
Select * from student
Where student_id not in (select student_id from absence);
這個子選擇查詢可以改寫如下所示的left join 查詢:
Select student. *
From student left join absence on student.student_id =absence.student_id
Where absence.student_id is null;
把非匹配型子選擇查詢改寫為關(guān)聯(lián)查詢是有規(guī)律可循的。下面這種形式的子選擇查詢:
Select * from tablel
Where column1 not in (select column2 from table2);
可以轉(zhuǎn)換為一個如下所示的關(guān)聯(lián)查詢:
Select tablel . *
From tablel left join table2 on tablel.column1=table2.column2
Where table2.column2 is null;
注意:這種改寫要求數(shù)據(jù)列table2.column2聲明為not null。