MySQL里面的子查詢(xún)實(shí)例
更新時(shí)間:2008年04月06日 01:12:20 作者:
最近學(xué)習(xí)php+mysql執(zhí)行操作,發(fā)現(xiàn)了這一篇實(shí)例代碼
一,子選擇基本用法
1,子選擇的定義
子迭擇允許把一個(gè)查詢(xún)嵌套在另一個(gè)查詢(xún)當(dāng)中。比如說(shuō):一個(gè)考試記分項(xiàng)目把考試事件分為考試(T)和測(cè)驗(yàn)(Q)兩種情形。下面這個(gè)查詢(xún)就能只找出學(xué)生們的考試成績(jī)
select * from score where event_id in (select event_id from event where type='T');
2,子選擇的用法(3種)
用子選擇來(lái)生成一個(gè)參考值
在這種情況下,用內(nèi)層的查詢(xún)語(yǔ)句來(lái)檢索出一個(gè)數(shù)據(jù)值,然后把這個(gè)數(shù)據(jù)值用在外層查詢(xún)語(yǔ)句的比較操作中。比如說(shuō),如果要查詢(xún)表中學(xué)生們?cè)谀骋惶斓臏y(cè)驗(yàn)成績(jī),就應(yīng)該使用一個(gè)內(nèi)層查詢(xún)先找到這一天的測(cè)驗(yàn)的事件號(hào),然后在外層查詢(xún)語(yǔ)句中用這個(gè)事件號(hào)在成績(jī)表里面找到學(xué)生們的分?jǐn)?shù)記錄。具體語(yǔ)句為:
select * from score where
id=(select event_id from event where date='2002-03-21' and type='Q');
需要注意的是:在應(yīng)用這種內(nèi)層查詢(xún)的結(jié)果主要是用來(lái)進(jìn)行比較操作的分法時(shí),內(nèi)層查詢(xún)應(yīng)該只有一個(gè)輸出結(jié)果才對(duì)。看例子,如果想知道哪個(gè)美國(guó)總統(tǒng)的生日最小,構(gòu)造下列查詢(xún)
select * from president where birth=min(birth)
這個(gè)查詢(xún)是錯(cuò)的!因?yàn)镸ySQL不允許在子句里面使用統(tǒng)計(jì)函數(shù)!min()函數(shù)應(yīng)該有一個(gè)確定的參數(shù)才能工作!所以我們改用子選擇:
select * from president where birht=(select min(birth) from presidnet);
exists 和 not exists 子選擇
上一種用法是把查間結(jié)果由內(nèi)層傳向外層、本類(lèi)用法則相反,把外層查詢(xún)的結(jié)果傳遞給內(nèi)層??赐獠坎樵?xún)的結(jié)果是否滿(mǎn)足內(nèi)部查間的匹配徑件。這種“由外到內(nèi)”的子迭擇用法非常適合用來(lái)檢索某個(gè)數(shù)據(jù)表在另外一個(gè)數(shù)據(jù)表里面有設(shè)有匹配的記錄
數(shù)據(jù)表t1 數(shù)據(jù)表t2
I1 C1 I2 C2
1
2
3 A
C 2
3
4 C
A
先找兩個(gè)表內(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)層查詢(xún)中的星號(hào)代表的是外層查詢(xún)的輸出結(jié)果。內(nèi)層查詢(xún)沒(méi)有必要列出有關(guān)數(shù)據(jù)列的名字,田為內(nèi)層查詢(xún)關(guān)心的是外層查詢(xún)的結(jié)果有多少行。希望大家能夠理解這一點(diǎn)
in 和not in 子選擇
在這種子選擇里面,內(nèi)層查詢(xún)語(yǔ)句應(yīng)該僅僅返回一個(gè)數(shù)據(jù)列,這個(gè)數(shù)據(jù)列里的值將由外層查詢(xún)語(yǔ)句中的比較操作來(lái)進(jìn)行求值。還是以上題為例
先找兩個(gè)表內(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);
好象這種語(yǔ)句更容易讓人理解,再來(lái)個(gè)例子
比如你想找到所有居住在A和B的學(xué)生。
select * from student where state in(‘A','B')
二, 把子選擇查詢(xún)改寫(xiě)為關(guān)聯(lián)查詢(xún)的方法。
1,匹配型子選擇查詢(xún)的改寫(xiě)
下例從score數(shù)據(jù)表里面把學(xué)生們?cè)诳荚囀录═)中的成績(jī)(不包括測(cè)驗(yàn)成績(jī)?。┎樵?xún)出來(lái)。
Select * from score where event_id in (select event_id from event where type='T');
可見(jiàn),內(nèi)層查詢(xún)找出所有的考試事件,外層查詢(xún)?cè)倮眠@些考試事件搞到學(xué)生們的成績(jī)。
這個(gè)子查詢(xún)可以被改寫(xiě)為一個(gè)簡(jiǎn)單的關(guān)聯(lián)查詢(xún):
Select score.* from score, event where score.event_id=event.event_id and event.event_id='T';
下例可以用來(lái)找出所有女學(xué)生的成績(jī)。
Select * from score where student_id in (select student_id form student where sex = ‘f');
可以把它轉(zhuǎn)換成一個(gè)如下所示的關(guān)聯(lián)查詢(xún):
Select * from score
Where student _id =student.student_id and student.sex ='f';
把匹配型子選擇查詢(xún)改寫(xiě)為一個(gè)關(guān)聯(lián)查詢(xún)是有規(guī)律可循的。下面這種形式的子選擇查詢(xún):
Select * from tablel
Where column1 in (select column2a from table2 where column2b = value);
可以轉(zhuǎn)換為一個(gè)如下所示的關(guān)聯(lián)查詢(xún):
Select tablel. * from tablel,table2
Where table.column1 = table2.column2a and table2.column2b = value;
(2)非匹配(即缺失)型子選擇查詢(xún)的改寫(xiě)
子選擇查詢(xún)的另一種常見(jiàn)用途是查找在某個(gè)數(shù)據(jù)表里有、但在另一個(gè)數(shù)據(jù)表里卻沒(méi)有的東西。正如前面看到的那樣,這種“在某個(gè)數(shù)據(jù)表里有、在另一個(gè)數(shù)據(jù)表里沒(méi)有”的說(shuō)法通常都暗示著可以用一個(gè)left join 來(lái)解決這個(gè)問(wèn)題。請(qǐng)看下面這個(gè)子選擇查詢(xún),它可以把沒(méi)有出現(xiàn)在absence數(shù)據(jù)表里的學(xué)生(也就是那些從未缺過(guò)勤的學(xué)生)給查出來(lái):
Select * from student
Where student_id not in (select student_id from absence);
這個(gè)子選擇查詢(xún)可以改寫(xiě)如下所示的left join 查詢(xún):
Select student. *
From student left join absence on student.student_id =absence.student_id
Where absence.student_id is null;
把非匹配型子選擇查詢(xún)改寫(xiě)為關(guān)聯(lián)查詢(xún)是有規(guī)律可循的。下面這種形式的子選擇查詢(xún):
Select * from tablel
Where column1 not in (select column2 from table2);
可以轉(zhuǎn)換為一個(gè)如下所示的關(guān)聯(lián)查詢(xún):
Select tablel . *
From tablel left join table2 on tablel.column1=table2.column2
Where table2.column2 is null;
注意:這種改寫(xiě)要求數(shù)據(jù)列table2.column2聲明為not null。
1,子選擇的定義
子迭擇允許把一個(gè)查詢(xún)嵌套在另一個(gè)查詢(xún)當(dāng)中。比如說(shuō):一個(gè)考試記分項(xiàng)目把考試事件分為考試(T)和測(cè)驗(yàn)(Q)兩種情形。下面這個(gè)查詢(xún)就能只找出學(xué)生們的考試成績(jī)
select * from score where event_id in (select event_id from event where type='T');
2,子選擇的用法(3種)
用子選擇來(lái)生成一個(gè)參考值
在這種情況下,用內(nèi)層的查詢(xún)語(yǔ)句來(lái)檢索出一個(gè)數(shù)據(jù)值,然后把這個(gè)數(shù)據(jù)值用在外層查詢(xún)語(yǔ)句的比較操作中。比如說(shuō),如果要查詢(xún)表中學(xué)生們?cè)谀骋惶斓臏y(cè)驗(yàn)成績(jī),就應(yīng)該使用一個(gè)內(nèi)層查詢(xún)先找到這一天的測(cè)驗(yàn)的事件號(hào),然后在外層查詢(xún)語(yǔ)句中用這個(gè)事件號(hào)在成績(jī)表里面找到學(xué)生們的分?jǐn)?shù)記錄。具體語(yǔ)句為:
select * from score where
id=(select event_id from event where date='2002-03-21' and type='Q');
需要注意的是:在應(yīng)用這種內(nèi)層查詢(xún)的結(jié)果主要是用來(lái)進(jìn)行比較操作的分法時(shí),內(nèi)層查詢(xún)應(yīng)該只有一個(gè)輸出結(jié)果才對(duì)。看例子,如果想知道哪個(gè)美國(guó)總統(tǒng)的生日最小,構(gòu)造下列查詢(xún)
select * from president where birth=min(birth)
這個(gè)查詢(xún)是錯(cuò)的!因?yàn)镸ySQL不允許在子句里面使用統(tǒng)計(jì)函數(shù)!min()函數(shù)應(yīng)該有一個(gè)確定的參數(shù)才能工作!所以我們改用子選擇:
select * from president where birht=(select min(birth) from presidnet);
exists 和 not exists 子選擇
上一種用法是把查間結(jié)果由內(nèi)層傳向外層、本類(lèi)用法則相反,把外層查詢(xún)的結(jié)果傳遞給內(nèi)層??赐獠坎樵?xún)的結(jié)果是否滿(mǎn)足內(nèi)部查間的匹配徑件。這種“由外到內(nèi)”的子迭擇用法非常適合用來(lái)檢索某個(gè)數(shù)據(jù)表在另外一個(gè)數(shù)據(jù)表里面有設(shè)有匹配的記錄
數(shù)據(jù)表t1 數(shù)據(jù)表t2
I1 C1 I2 C2
1
2
3 A
C 2
3
4 C
A
先找兩個(gè)表內(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)層查詢(xún)中的星號(hào)代表的是外層查詢(xún)的輸出結(jié)果。內(nèi)層查詢(xún)沒(méi)有必要列出有關(guān)數(shù)據(jù)列的名字,田為內(nèi)層查詢(xún)關(guān)心的是外層查詢(xún)的結(jié)果有多少行。希望大家能夠理解這一點(diǎn)
in 和not in 子選擇
在這種子選擇里面,內(nèi)層查詢(xún)語(yǔ)句應(yīng)該僅僅返回一個(gè)數(shù)據(jù)列,這個(gè)數(shù)據(jù)列里的值將由外層查詢(xún)語(yǔ)句中的比較操作來(lái)進(jìn)行求值。還是以上題為例
先找兩個(gè)表內(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);
好象這種語(yǔ)句更容易讓人理解,再來(lái)個(gè)例子
比如你想找到所有居住在A和B的學(xué)生。
select * from student where state in(‘A','B')
二, 把子選擇查詢(xún)改寫(xiě)為關(guān)聯(lián)查詢(xún)的方法。
1,匹配型子選擇查詢(xún)的改寫(xiě)
下例從score數(shù)據(jù)表里面把學(xué)生們?cè)诳荚囀录═)中的成績(jī)(不包括測(cè)驗(yàn)成績(jī)?。┎樵?xún)出來(lái)。
Select * from score where event_id in (select event_id from event where type='T');
可見(jiàn),內(nèi)層查詢(xún)找出所有的考試事件,外層查詢(xún)?cè)倮眠@些考試事件搞到學(xué)生們的成績(jī)。
這個(gè)子查詢(xún)可以被改寫(xiě)為一個(gè)簡(jiǎn)單的關(guān)聯(lián)查詢(xún):
Select score.* from score, event where score.event_id=event.event_id and event.event_id='T';
下例可以用來(lái)找出所有女學(xué)生的成績(jī)。
Select * from score where student_id in (select student_id form student where sex = ‘f');
可以把它轉(zhuǎn)換成一個(gè)如下所示的關(guān)聯(lián)查詢(xún):
Select * from score
Where student _id =student.student_id and student.sex ='f';
把匹配型子選擇查詢(xún)改寫(xiě)為一個(gè)關(guān)聯(lián)查詢(xún)是有規(guī)律可循的。下面這種形式的子選擇查詢(xún):
Select * from tablel
Where column1 in (select column2a from table2 where column2b = value);
可以轉(zhuǎn)換為一個(gè)如下所示的關(guān)聯(lián)查詢(xún):
Select tablel. * from tablel,table2
Where table.column1 = table2.column2a and table2.column2b = value;
(2)非匹配(即缺失)型子選擇查詢(xún)的改寫(xiě)
子選擇查詢(xún)的另一種常見(jiàn)用途是查找在某個(gè)數(shù)據(jù)表里有、但在另一個(gè)數(shù)據(jù)表里卻沒(méi)有的東西。正如前面看到的那樣,這種“在某個(gè)數(shù)據(jù)表里有、在另一個(gè)數(shù)據(jù)表里沒(méi)有”的說(shuō)法通常都暗示著可以用一個(gè)left join 來(lái)解決這個(gè)問(wèn)題。請(qǐng)看下面這個(gè)子選擇查詢(xún),它可以把沒(méi)有出現(xiàn)在absence數(shù)據(jù)表里的學(xué)生(也就是那些從未缺過(guò)勤的學(xué)生)給查出來(lái):
Select * from student
Where student_id not in (select student_id from absence);
這個(gè)子選擇查詢(xún)可以改寫(xiě)如下所示的left join 查詢(xún):
Select student. *
From student left join absence on student.student_id =absence.student_id
Where absence.student_id is null;
把非匹配型子選擇查詢(xún)改寫(xiě)為關(guān)聯(lián)查詢(xún)是有規(guī)律可循的。下面這種形式的子選擇查詢(xún):
Select * from tablel
Where column1 not in (select column2 from table2);
可以轉(zhuǎn)換為一個(gè)如下所示的關(guān)聯(lián)查詢(xún):
Select tablel . *
From tablel left join table2 on tablel.column1=table2.column2
Where table2.column2 is null;
注意:這種改寫(xiě)要求數(shù)據(jù)列table2.column2聲明為not null。
相關(guān)文章
將MySQL查詢(xún)結(jié)果按值排序的簡(jiǎn)要教程
這篇文章主要介紹了將MySQL查詢(xún)結(jié)果按值排序的簡(jiǎn)要教程,不過(guò)同樣需要對(duì)結(jié)果進(jìn)行檢查而決定是否使用order by等其他語(yǔ)句,需要的朋友可以參考下2015-12-12mysql DBA:mysqladmin常用命令總結(jié)
mysqladmin是MySQL一個(gè)重要的客戶(hù)端,最常見(jiàn)的是使用它來(lái)關(guān)閉數(shù)據(jù)庫(kù),除此,該命令還可以了解MySQL運(yùn)行狀態(tài)、進(jìn)程信息、進(jìn)程等,本文介紹一下如何使用mysqladmin extended-status(因?yàn)闆](méi)有"歧義",所以可以使用ext代替)了解MySQL的運(yùn)行狀態(tài)2014-03-03mysql多版本并發(fā)控制MVCC的實(shí)現(xiàn)
這篇文章主要介紹了mysql多版本并發(fā)控制MVCC的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10Windows 10 與 MySQL 5.5 安裝使用及免安裝使用詳細(xì)教程(圖文)
本文介紹Windows 10環(huán)境下,MySQL 5.5的安裝使用及免安裝使用教程,本文提供了資源下載及相關(guān)問(wèn)題解決方案,非常不錯(cuò),需要的朋友參考下2017-07-07Linux下安裝Mysql多實(shí)例作為數(shù)據(jù)備份服務(wù)器實(shí)現(xiàn)多主到一從多實(shí)例的備份
由于第一次接觸LINUX,花了三天時(shí)間才算有所成就,發(fā)出來(lái)希望可以給大伙帶來(lái)方便2010-07-07MySQL實(shí)現(xiàn)merge?into四種方法代碼實(shí)例
Merge?into是一個(gè)數(shù)據(jù)庫(kù)操作術(shù)語(yǔ),通常用于將兩個(gè)或多個(gè)表中的數(shù)據(jù)合并到一個(gè)表中,這篇文章主要給大家介紹了關(guān)于MySQL實(shí)現(xiàn)merge?into四種方法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07dubbo中zookeeper請(qǐng)求超時(shí)問(wèn)題:mybatis+spring連接mysql8.0.15的配置
這篇文章主要介紹了dubbo中zookeeper請(qǐng)求超時(shí)問(wèn)題:mybatis+spring連接mysql8.0.15的配置,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01