MySQL?衍生表(Derived?Tables)的使用
在SQL的查詢語(yǔ)句select …. from …中,跟在from子句后面的通常是一張擁有定義的實(shí)體表,而有的時(shí)候我們會(huì)用子查詢來扮演實(shí)體表的角色,這個(gè)在from子句中的子查詢會(huì)返回一個(gè)結(jié)果集,這個(gè)結(jié)果集可以像普通的實(shí)體表一樣查詢、連接,這個(gè)子查詢的結(jié)果集就叫做衍生表。
一、衍生表簡(jiǎn)介
衍生表常用在需要對(duì)數(shù)據(jù)進(jìn)行臨時(shí)處理的場(chǎng)景,即對(duì)表直接查詢無(wú)法得出結(jié)果,需要對(duì)數(shù)據(jù)進(jìn)行加工,然后在加工基礎(chǔ)上與原數(shù)據(jù)再次進(jìn)行連接,才能得出結(jié)果。
示例數(shù)據(jù)準(zhǔn)備
例如下面一的張考試成績(jī)表,subject_id代表不同的科目,score代表分?jǐn)?shù):
create table exam( id int not null auto_increment primary key, subject_id int, student varchar(12), score int); insert into exam values(null,1,'小紅',89), (null,1,'小橙',76), (null,1,'小黃',89), (null,1,'小綠',95), (null,2,'小青',77), (null,2,'小藍(lán)',83), (null,2,'小紫',99); select * from exam;
1.1 衍生表基本用法
現(xiàn)要求:找出每個(gè)科目得分最高那條記錄,這個(gè)問題需要拆分成2步完成:
第一步:找出每個(gè)科目的最高分
select subject_id, max(score) score from exam group by subject_id;
第二步:將上一步的結(jié)果與exam表進(jìn)行連接,找出具體的記錄:
select e.* from exam e, (select subject_id, max(score) score from exam group by subject_id) d where d.subject_id=e.subject_id and d.score=e.score;
- 這里將第一步的查詢放在括號(hào)中,并取一個(gè)別名d。
- 通過別名d,MySQL可以像引用實(shí)體表一樣引用子查詢的結(jié)果集(衍生表)。
1.2 自定義列名
在給衍生表定義別名時(shí),可以同時(shí)定義列名,方法是在別名后的括號(hào)內(nèi)列出列名,要注意列名的數(shù)量要和子查詢返回的列數(shù)量相同:
select a, b, d from (select 1,2,3,4) d(a,b,c,d);
1.3 衍生表的局限
衍生表目前的局限是它是一個(gè)獨(dú)立的子查詢,在生成結(jié)果集之前無(wú)法和from表中的其他表產(chǎn)生關(guān)聯(lián),如果產(chǎn)生衍生表的子查詢成本非常高,而最后與其他表連接后只使用了一小部分?jǐn)?shù)據(jù),那么這個(gè)性能浪費(fèi)是非常嚴(yán)重的。
例如上面的例子中,如果表中有10萬(wàn)個(gè)科目,而我最終結(jié)果只涉及2個(gè)科目,那么在衍生表中對(duì)10萬(wàn)個(gè)科目進(jìn)行g(shù)roup by顯然是沒有必要的,這種情況我們需要提前將外層謂語(yǔ)條件(where)傳入衍生表中,避免處理不必要的數(shù)據(jù),但這也意味著謂語(yǔ)條件在外層寫了一遍,必須在衍生表中再寫一遍,增加了SQL復(fù)雜度。
在MySQL 8.0.14版本后,通過橫向衍生表(lateral關(guān)鍵字),可以在衍生表中引用from子句中之前出現(xiàn)的表,可以完美解決上述局限。
MySQL 橫向衍生表(Lateral Derived Tables)
到此這篇關(guān)于MySQL 衍生表(Derived Tables)的使用的文章就介紹到這了,更多相關(guān)MySQL 衍生表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL啟動(dòng)報(bào)錯(cuò)提示發(fā)生系統(tǒng)錯(cuò)誤5,拒絕訪問的原因和解決方法
使用命令net start mysql啟動(dòng)數(shù)據(jù)庫(kù)服務(wù)時(shí)候,出現(xiàn)如下錯(cuò)誤提示發(fā)生系統(tǒng)錯(cuò)誤5,拒絕訪問,所以本文給大家介紹了MySQL啟動(dòng)報(bào)錯(cuò)提示發(fā)生系統(tǒng)錯(cuò)誤5,拒絕訪問的原因和解決方法,需要的朋友可以參考下2024-01-01MySQL實(shí)現(xiàn)主從復(fù)制的原理詳解
這篇文章主要為大家介紹了MySQL的主從復(fù)制是怎么實(shí)現(xiàn)的,文中有相關(guān)的圖文介紹和代碼示例,具有一定的參考價(jià)值,感興趣的同學(xué)跟著小編一起來學(xué)習(xí)吧2023-07-07詳解MySql基本查詢、連接查詢、子查詢、正則表達(dá)查詢
本篇文章采用了圖文相結(jié)合的方式介紹了數(shù)據(jù)庫(kù)的四大查詢方式:基本查詢、連接查詢、子查詢、正則表達(dá)查詢,需要了解的朋友可以參考下2015-07-07解決MySql8.0 查看事務(wù)隔離級(jí)別報(bào)錯(cuò)的問題
這篇文章主要介紹了解決MySql8.0 查看事務(wù)隔離級(jí)別報(bào)錯(cuò)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10Mysql數(shù)據(jù)庫(kù)性能優(yōu)化二
這篇文章主要介紹了Mysql數(shù)據(jù)庫(kù)性能優(yōu)化二 的相關(guān)資料,需要的朋友可以參考下2016-04-04MySQL 8.0.13設(shè)置日期為0000-00-00 00:00:00時(shí)出現(xiàn)的問題解決
這篇文章主要介紹了MySQL 8.0.13設(shè)置日期為0000-00-00 00:00:00時(shí)出現(xiàn)的問題解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-01-01MySQL插入時(shí)間戳字段的值實(shí)現(xiàn)
在MySQL中,我們經(jīng)常會(huì)遇到需要插入時(shí)間戳字段的情況,包括使用NOW()函數(shù)插入當(dāng)前時(shí)間戳,使用FROM_UNIXTIME()插入指定時(shí)間戳,本文就來介紹一下,感興趣的可以了解一下2024-09-09