要理解除操作,我們首先要引入「象集」這個概念。
其實象集很簡單,就跟我們學過的函式對應關係差不多,只不過函式是「一對一」或者「多對一」,而象集恰好相反,是「一對多」。
引入乙個例子看看。假設我們有一張學生選課表sc(sno, cno, grade),其中sno的學生的學號,cno是課程號,grade是分數。這張表記錄了學生選修某門課的成績。
snocno
grade
2020001
00193
2020001
00295
2020001
00390
2020002
00198
2020002
00387
2020003
00275
(備註:一共只有三門選修課:「001」,「002」,「003」)
我們不給出「象集」的任何定義,先直接求出象集,求完之後,你也就明白了,注意前面說的一對多的關係。
2020001的象集
2020002的象集
2020003的象集
有了象集的概念後,我們現在來理解「除運算」。假設我們有兩個關係r(x,y)和關係s(y,z),那麼
r÷s = 其中yx為x在r中的象集。
是不是懵逼了?什麼鬼東西?
其實啊,這都是紙老虎,沒那麼難!我們只需要從列(屬性)和行(元組)來理解就可以了。
列(屬性):r ÷ s得到的新的關係(表),它的列是從r中的列中去掉r和s相交的列。
行(元組):r中每乙個x對應的象集應該包含s的投影
這就是「除運算」,這麼說可能還是有些抽象,我們繼續用上面給出的學生選課例子來研究,為了方便我們暫時先將sc的grade屬性去掉,然後我們再加乙個課程關係c(cno,cname)
sc:sno
cno2020001
0012020001
0022020001
0032020002
0012020002
0032020003
002c:
cnocname
001作業系統
002計算機網路
003資料結構
我們通過這兩個表求sc÷c,我們從列和行兩個步驟來進行求解。
第一步(列):sc和c公共的列是cno,所以r÷s必然只剩下r中的sno列,故列先被確定下來了
sc÷c
sno2020001
2020001
2020001
2020002
2020002
2020003
第二步(行):
c的投影為(001,002,003),而sc中sno的象集中包含(001,002,003)的只有2020001,故,行也被確定下來了
sc÷c
sno2020001
聰明的你可能已經發現,sc÷c表示的含義是「查詢選修了全部課程的學生」,其實除操作非常適合用於求「至少使用了…的全部」之類的查詢
我們剛剛討論了除操作的關係代數,那麼怎麼用sql語句來表示呢?事實上,sql語言並沒有定義除操作,甚至連全稱量詞都沒有,但是有存在量詞exists 和 not exists,所以通常的思路就是將全程量詞轉變為存在量詞來實現除操作。這種也是大多數教材普遍的**,但是我們今天不用這種方法,因為那種方法有些繞,使得我們很容易看懂別人寫的,但是讓自己寫卻寫不出來。所以我們用另一種非常好理解的方式:從除操作的定義出發來解決,不過這要求我們知道什麼是右外連線,不用慌,活著就是為了折騰,我都為你準備好了。
什麼是「外連線」呢?這恐怕得從「連線(嚴格來講應該是自然連線)」說起!我們還是使用上面的sc表和c表,注意表的變化!
sc:sno
cno2020001
0012020001
0022020001
003c:
cnocname
001作業系統
002計算機網路
003資料結構
004計算機組成原理
當我們對兩張表做連線的時候,我們會將sc和c中cno相等的元組拼接起來,於是得到新的關係
sc∞c:
snocno
cname
2020001
001作業系統
2020001
002計算機網路
2020001
003資料結構
細心的你一定發現了,計算機組成原理這麼課因為沒人選,所以連線運算時就丟失了,這就是所謂的「懸浮元組」。為了讓懸浮元組也出現,於是人們就折騰出了外連線、左外連線、右外連線,我們這裡直接說右外連線吧。
當c中的元組的cno與sc中的元組的cno沒有對應關係的時候,我們不丟棄這個選組,仍然將其顯示出來,用null填充沒有匹配的字段,也就是下面這樣:
sc∝c:
snocno
cname
2020001
001作業系統
2020001
002計算機網路
2020001
003資料結構
null
004計算機組成原理
了解了右外連線後我們就可以利用它這個性質來做除運算了。我們再次使用上面的例子(注意sc和c的變化)
sc:sno
cnograde
2020001
00193
2020001
00295
2020001
00390
2020002
00198
2020002
00387
2020003
00275
c:cno
cname
001作業系統
002計算機網路
003資料結構
現在我們求選修了全部課程的學生的學號
我們先寫關係代數:
① 全部課程的課程號:∏cno(c)
②除:sc ÷ ∏cno(c)
③投影取學號:∏sno(sc ÷ ∏cno(c))
關係代數很容易寫出,但是sql語句稍微有些複雜,現在我們就用外連線來實現。
sql語句
select
distinct sno
from sc a
where
notexists
(select
*from
(select sno, cno from sc b where a.sno = b.sno) x
right
outer
join
(select cno from c) y
on x.cno = y.cno
where x.sno is
null
);
莫慌,我來解釋一下這條sql語句。拿資料說話,注意我調整了一下
sc:sno
cnograde
2020002
00275
2020001
00193
2020001
00295
2020001
00390
c:cno
cname
001作業系統
002計算機網路
003資料結構
外層迴圈先取出一條記錄select distinct sno from sc a
:(2020002, 002, 75)
我們拿到這個學生的學號2020002,然後找出他選修的所有課程:select sno, cno from sc b where a.sno = b.sno
:只有一門課002
然後用002與所有課程做外連線,得到如下的結果:
snocno
null
0012020002
002null
003顯然,有兩個sno為空了,所以not exists不通過,2020002不是選修了全部課程的學生
以同樣的方式對2020001操作得到下面的結果
snocno
2020001
0012020001
0022020001
003sno沒有null,所以2020001是選修了全部課程的學生,將其學號輸出。
利用SQL語言實現關係代數操作
目錄 1.並交差的處理 2.舉例 3.空值的處理 4.內連線和外連線 1.並 交 差 1 sql語言 union,intersect,except 2 語法格式 子查詢1 通常情況下自動刪除重複元組,不帶all 若要保留重複元組,則要帶 all 3 假設子查詢1 的乙個元組出現 m 次,子查詢2 的...
關係代數中的除法
在介紹關係代數的除法以前我們必須熟悉象集的概念 給定乙個關係r x,z x 和z 為屬性組。當 t x x 時,x 在 r 中的象集 images set 為 zx 表示r中屬性組x上值為x的諸元組在屬性組z上分量的集合。s在b2上的象集為上圖右方的關係。r與s的除運算得到乙個新的關係p x p是r...
關係代數中的除法運算
這個概念的描述的非常抽象,剛開始學習的同學完全不知所云。這裡通過乙個例項來說明除法運算的求解過程 設有關係r s 如圖所示,求r s 的結果 求解步驟過程 第一步 找出關係r和關係s中相同的屬性,即y屬性。在關係s中對y做投影 即將y列取出 所得結果如下 第二步 被除關係r中與s中不相同的屬性列是x...