檢索所有課程都選修的的學生的學號與姓名


  這是SHU數據庫原理上機題目中的一道。全部題目:http://www.docin.com/p-739281393.html

  代碼網上有:

  select xh,xm

  from s

  where not exists

  (select * from c 

  where  not exists

  (select * from e

  where xh=s.xh and kh=c.kh

  )

  ) 

  其中s是學生表,c是課程表,e是選課表

  上課沒注意聽,實驗驗收前看了很久沒看懂。網上的講解沒看明白,並且還有錯的講解(該頁的最后會有)。直接跟老師說這個不懂,老師讓我中午去找他。花了20多分鍾,我懂了。老師說上課還是要聽,我深以為然。

  這代碼有三種方式去理解:

  1、離散數學中的謂詞邏輯演算系統

  先來復習一下

  ∃x∀yR(xy) :存在x對於任意的y滿足關系R(xy)。

  ﹁∀yW(y):不是所有的y都滿足關系W(y),那么就是存在y不滿足關系R,即∃y﹁W(y)

  令f(x):x是學生;g(y):y是課程;r(xy):學生x選修了課程y。

  “所有課程都選修的學生”可以表示為∃x∈f(x)∧∀y∈g(y)∧r(xy) ,就是存在學生任意一門課都選了。

  SQL語言中沒有全稱量詞,所以通過雙重否定來實現

  ﹁﹁((∃x∈f(x)∧∀y∈g(y))∧r(xy)) => ∃x∈f(x)∧﹁(∃y∈g(y)∧﹁r(xy))

  對於﹁∀yR(xy),理解為不是所有的y都滿足關系R,那么就是存在y不滿足關系R,∃y﹁R(xy)

  然后用這個式子與上面的代碼對照。  

  ﹁就相當於一個not exists,其實相當於是select

  select xh,xm from s  等價於∃x∈f(x)

  select * from c 等價於 ∃y∈g(y)

  where  not exists(select * from ewhere xh=s.xh and kh=c.kh) 等價於 ﹁r(xy) 

 

  

  2、用C++的編程思想來理解

  for(int i=0;i<s.length;i++)

  {

    for(int j=0;j<c.length;j++)

    {

      if(學生i沒有選修j課程) break;

    }

    if(j==c.length) i就是選修了所有課程的學生;

  }

  兩個not exists可以這樣解釋,依次從學生表里找一個學生,讓這個學生去選課表里找課程。如果遍歷到某課程該學生沒有選修,就結束,然后開始遍歷下一個學生。如果是遍歷完課表的話,就代表着該學生學修了所有的課程。

  也就是說我們不去用語言來翻譯代碼,換種思維來理解它。

 

  3、純粹記憶

  如果查詢“全部”內容,需用到全稱量詞,但SQL語言只提供存在量詞,我們用存在量詞雙重否定來解決

  SELECT <查詢內容> FROM 表1 WHERE

    NOT EXISTS(SELECT * FROM 表2 WHERE

    NOT EXISTS(SELEST * FROM 表3 WHERE

               表3與表1聯接條件 AND 表3與表2聯接條件))

  表1是查詢結果所需要的表

  表2是全部內容所在的表

  表3是將聯接上述兩表的表

 例:1.查詢使用了全部零件的工程名稱(理解為沒有零件是不用的)

    2.查詢至少用了供應商S1所供應的的全部零件的工程號

  這種方法是不去理解no exists的原理,記住格式就好了。應付考試專用。

 

  關於上面提到的錯誤的講解:

  有人說代碼可以這樣寫:

  select xh,xm
  from s
  where xh in
  (
  select xh from e group by xh
  having count(*) = (select count(*) from c)
  )

  這樣理解的,統計課程的數量,記為n,假如某學生所修的課程的數量為n。那么該學生就是選修所有課程的人。

  剛開始我也以為這樣可以的。因為邏輯上是正確的。

  我在課程表c中添加了幾組數據,使得有人選修了所有課號的課。但是運行最上面的代碼(代碼1)和這條代碼(代碼2)的運行結果是不同。

  那么導致結果不同的原因是什么呢?課程表c里有重修課程,也就是有課程雖然是相同的課程號,但是由於開課的時間不同,所以它們不算一門課。

  那么上面的代碼有可取的地方么?有,特殊的情況是可以用的,就是事件是唯一的的時候。

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM