非相關(guān)子查詢和相關(guān)子查詢執(zhí)行過程詳解
轉(zhuǎn)自csdn博客@馬世超
前段時(shí)間有一個(gè)相關(guān)子查詢的SQL語句,看不太懂他是如何執(zhí)行的,為什么會(huì)出現(xiàn)那個(gè)結(jié)果。著實(shí)糾結(jié)了一把。下面來講一下非相關(guān)子查詢和相關(guān)子查詢的執(zhí)行過程是怎樣的。
非相關(guān)子查詢
先看一個(gè)非相關(guān)子查詢到sql語句。
需求:查詢學(xué)生表student和學(xué)生成績表grade中成績?yōu)?0分的學(xué)生的基本信息。
select t.sno,t.sname,t.sage,t.sgentle,t.sbirth,t.sdept from student t where t.sno in (select f.sno from garde f where f.score=70)
這個(gè)sql語句的執(zhí)行時(shí)是簡單的,
1、在grade表中找出成績?yōu)?0的學(xué)生學(xué)號(hào)sno,再將該學(xué)號(hào)返回到父查詢作為where子句的條件。
2、在student表中找到該學(xué)號(hào)學(xué)生的其他基本信息。
相關(guān)子查詢
所謂相關(guān)子查詢,是指求解相關(guān)子查詢不能像求解普通子查詢那樣,一次將子查詢求解出來,然后求解父查詢。相關(guān)子查詢的內(nèi)層查詢由于與外層查詢有關(guān),因此必須反復(fù)求值。
下面看相關(guān)子查詢的sql語句。
需求:在學(xué)生表student和學(xué)生成績表grade找出參加了“計(jì)算機(jī)基礎(chǔ)”課程并且分?jǐn)?shù)在80分以上的所有學(xué)生信息。
select t.sno,t.sname,t.sage,t.sgentle,t.sbirth,sdept from student t where 80<=(select f.score from grade f where f.sno=t.sno and f.cname='計(jì)算機(jī)基礎(chǔ)')
該子查詢的執(zhí)行流程:
1、 先從父查詢的student表中取出第一條記錄的sno值,進(jìn)入子查詢中,比較其where子句的條件“where f.sno=t.sno and f.cname=’計(jì)算機(jī)基礎(chǔ)’”,符合則返回score成績。
2、 返回父查詢,判斷父查詢的where子句條件80<=返回的score,如果條件為true,則返回第1條記錄。
3、 從父查詢的student表中取出第2條數(shù)據(jù),重復(fù)上述操作,直到所有父查詢中的表中記錄取完為止。
總結(jié)
對(duì)比這兩個(gè)查詢的sql執(zhí)行過程可以看出,相關(guān)子查詢和非相關(guān)子查詢的不同點(diǎn)在于,相關(guān)子查詢依賴于父查詢,父查詢和子查詢是有聯(lián)系的,尤其在子查詢的where語句中更是如此。明白了他們的執(zhí)行過程,再去看相關(guān)子查詢的代碼,一下子就明白了。