數(shù)據(jù)庫(kù)原理與應(yīng)用(9)嵌套子查詢、聯(lián)合查詢、交叉連接、自然連接
(1)嵌套子查詢
【知識(shí)點(diǎn)】
? 子查詢是指在一個(gè)查詢里嵌套了其他的若干查詢,即在一個(gè)select語句的where或having或from子句中包含了另一個(gè)select查詢語句。外層查詢語句稱為主查詢(或父查詢),內(nèi)層查詢語句稱為子查詢。
? 根據(jù)內(nèi)層查詢的條件是否依賴于外層查詢,子查詢分為相關(guān)子查詢和不相關(guān)子查詢。
? 子查詢必須用小括號(hào)括起來,子查詢與父查詢嵌套時(shí)需要相應(yīng)的運(yùn)算符,包括比較運(yùn)算符、in、any(some)、all、exists等。運(yùn)算符的選擇取決于子查詢的返回結(jié)果。

? 運(yùn)算符ALL和ANY常與某個(gè)關(guān)系比較運(yùn)算符結(jié)合在一起使用,以便測(cè)試子?xùn)嗽兊慕Y(jié)果。它們會(huì)測(cè)試比較值與子查詢返回的全部或部分值是否匹配。SOME是ANY的同義詞。
??EXISTS后面的參數(shù)是一個(gè)任意的子查詢。其只會(huì)測(cè)試某個(gè)子?xùn)嗽兪欠穹祷亓诵?。如果有返回,則EXISTS的結(jié)果為真,而NOT EXISTS的結(jié)果為假。
? 當(dāng)子查詢返回多行時(shí)使用in運(yùn)算符引出子查詢,用等號(hào)引出的子查詢都可以用in替換。
? 對(duì)于比較復(fù)雜的查詢要求,可以使用select語句實(shí)現(xiàn)子查詢的多重嵌套。
【例題】
·判斷題
(1)一個(gè)SELECT語句只能嵌套在一個(gè)SELECT中。F
(理論上可以嵌套n層,假設(shè)不考慮運(yùn)行效率的話)
(2)子查詢的SELECT語句中不能使用ORDER BY子句。T
(3)如果子查詢的返回值多個(gè),那么可以使用比較運(yùn)算符 ‘=’。F
(這個(gè)時(shí)候必須用in引出子查詢)
·選擇題
(1)在SQL語言中,子查詢是嵌入到另一個(gè)查詢語句之中的查詢語句。
(2)SQL的嵌套子查詢,可以嵌套n層。
(3)已知S(S#,SN,AGE,SEX), S# 學(xué)號(hào),SN 姓名。若要檢索所有比'丁真'年齡大的學(xué)生姓名、年齡和性別,正確的SELECT語句是SELECT SN, AGE, SEX FROM S WHERE AGE>(SELECT AGE FROM S WHERE SN='丁真');
(4)中間連接不屬于連接種類。
(5)子查詢的結(jié)果可以是1或多個(gè)值。
(6)子查詢和父查詢可以使用兩張或更多不同的表,也可以共用一張表。
·填空題
(1)
某公司的員工關(guān)系employees(工號(hào),姓名,工資,部門,主管ID,工種ID),現(xiàn)需查詢工資比何平高的員工的工號(hào),姓名、工資。那么請(qǐng)完成下面SQL語句:
select 工號(hào),姓名,工資 from employees where 工資 >( select 工資 from employees where 姓名='何平');
(2)
某工程項(xiàng)目的部分關(guān)系如下:
職工(職工編號(hào),姓名,性別,居住城市)
項(xiàng)目(項(xiàng)目編號(hào),項(xiàng)目名稱,狀態(tài),城市,負(fù)責(zé)人編號(hào))
職工項(xiàng)目(職工編號(hào),項(xiàng)目編號(hào))
其中:職工可以同時(shí)參加多個(gè)項(xiàng)目,一個(gè)項(xiàng)目需要多個(gè)職工參加。
那么如何查詢職工編號(hào)為'000015',參加的項(xiàng)目名稱和城市。
select 項(xiàng)目名稱,城市 from 項(xiàng)目 where 項(xiàng)目編號(hào) in (select 項(xiàng)目編號(hào) from 職工項(xiàng)目 where 職工編號(hào)='000015');
·編程題
(1)查詢信息學(xué)院學(xué)生所選修的課程號(hào)和成績(jī)。
select cno,score from sc where sno in (select sno from students where sdept='信息學(xué)院');
(2)查詢與“陸毅”同一個(gè)系的同學(xué)姓名。
select sname from students where sdept=(select sdept from students where sname='陸毅') and sname!='陸毅';
(3)查詢“19信管2”班的學(xué)生所選修的課程號(hào)。
select cno from sc where sno in (select sno from students where class='19信管2');
(4)查詢“陳曉東”同學(xué)所選課程的課號(hào)及成績(jī)。
select cno,score from sc where sno in (select sno from students where sname='陳曉東');
(5)查詢選修了課號(hào)為“0000034”的學(xué)生學(xué)號(hào)和姓名。
select sno,sname from students where sno in (select sno from sc where cno='0000034');
(6)查詢“0000008”號(hào)課程不及格的學(xué)生信息。
select * from students where sno in (select sno from sc where cno='0000008' and score<60);
(7)查詢李小鵬同學(xué)所選課程名稱。
select cname from course where cno in (select cno from sc where sno in (select sno from students where sname='李小鵬'));
(8)查詢“王珊”老師所授課程的課程名稱。
select cname from course where cno in (select cno from teaching where tno in (select tno from teachers where tname='王珊'));
(9)查詢“陸以寧”所購(gòu)商品產(chǎn)地所有商品的編號(hào)。
select gno from goods where place in (select place from goods where gno in (select gno from sale where vno in (select vno from vip where vname='陸以寧')));
(10)查詢與“得力鉛筆”同一公司生產(chǎn)的的商品的信息。
select * from goods where company in (select company from goods where gname='得力鉛筆');
(11)查詢售價(jià)最高的商品的名稱。
select gname from goods where price in(select max(price) from goods);
(12)查詢陸以寧購(gòu)買的商品名稱。
select gname from goods where gno in (select gno from sale where vno in (select vno from vip where vname='陸以寧'));
(13)查詢購(gòu)買舒膚佳沐浴露商品產(chǎn)地所有商品的會(huì)員姓名。
select vname from vip where vno in (select vno from sale where gno in (select gno from goods where place in (select place from goods where gname='舒膚佳沐浴露')));
(14)查詢購(gòu)買陸以寧所購(gòu)買商品產(chǎn)地所有商品的會(huì)員姓名。
select vname from vip where vno in (select vno from sale where gno in (select gno from goods where place in (select place from goods where gno in(select gno from sale where vno in (select vno from vip where vname='陸以寧')))));
(2)聯(lián)合查詢
? union,將多次查詢(多條select語句)的結(jié)果,在字段數(shù)相同的情況下,在記錄的層次上進(jìn)行拼接。
??聯(lián)合查詢由多條select語句構(gòu)成,每條select語句獲取的字段數(shù)相同,但與字段類型無關(guān)。
? 【例】
select * from class
union distinct / all
select * from class;
(3)交叉連接
? 交叉連接(cross join)為不帶連接條件的查詢,返回被連接的兩個(gè)表所有數(shù)據(jù)行的笛卡爾積,即用左表中的每一行與右表中的每一行分別進(jìn)行連接。因此,結(jié)果集中的行數(shù)是左表的行數(shù)乘以右表的行數(shù)(排列數(shù))。
? 交叉連接沒有特定的實(shí)際含義,通常用于測(cè)試所有的可能情況。
? 【例】select * from students cross join course;
(4)自然連接
? 自然連接(nature join)連接條件忽略不寫。
? 【例】select * from students nature join register;