關係代數中的除操作怎麼用SQL語句表示?

2021-10-03 16:24:11 字數 4118 閱讀 9586

要理解除操作,我們首先要引入「象集」這個概念。

其實象集很簡單,就跟我們學過的函式對應關係差不多,只不過函式是「一對一」或者「多對一」,而象集恰好相反,是「一對多」。

引入乙個例子看看。假設我們有一張學生選課表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...