mysql,SQL標準,多表查詢中內連接,外連接,自然連接等詳解之查詢結果集的笛卡爾積的演化

来源:http://www.cnblogs.com/intsmaze/archive/2016/03/11/5265904.html
-Advertisement-
Play Games

先附上數據。 CREATE TABLE `course` ( `cno` int(11) NOT NULL, `cname` char(30) CHARACTER SET utf8 NOT NULL, `ctime` int(11) NOT NULL, `scount` int(11) NOT NU


先附上數據。

CREATE TABLE `course` (
  `cno` int(11) NOT NULL,
  `cname` char(30) CHARACTER SET utf8 NOT NULL,
  `ctime` int(11) NOT NULL,
  `scount` int(11) NOT NULL,
  `ctest` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `course` VALUES ('4', '應用數學基礎', '48', '120', '2016-03-10 10:08:29');
INSERT INTO `course` VALUES ('5', '生物工程概論', '32', '80', '2016-03-10 10:09:24');
INSERT INTO `course` VALUES ('1', '電腦軟體基礎', '32', '70', '2016-03-10 10:09:47');
INSERT INTO `course` VALUES ('2', '電腦硬體基礎', '24', '80', '2016-03-10 10:10:28');
INSERT INTO `course` VALUES ('8', '模擬電路設計', '28', '90', '2016-04-06 10:11:02');
INSERT INTO `course` VALUES ('7', '機械設計實踐', '48', '68', '2016-03-10 10:11:29');
INSERT INTO `course` VALUES ('3', '生物化學', '32', '40', '2016-03-29 10:11:54');
INSERT INTO `course` VALUES ('9', '資料庫設計', '16', '80', '2016-03-10 10:12:14');
INSERT INTO `course` VALUES ('6', '設計理論', '28', '45', '2016-03-10 10:12:33');
INSERT INTO `course` VALUES ('10', '電腦入門', '24', '150', '2016-03-10 10:12:53');
INSERT INTO `course` VALUES ('11', '數字電路設計基礎', '30', '125', '2016-03-10 10:13:10');

CREATE TABLE `student` (
  `sno` char(4) CHARACTER SET utf8 DEFAULT NULL,
  `sname` char(10) CHARACTER SET utf8 DEFAULT NULL,
  `dname` char(10) CHARACTER SET utf8 DEFAULT NULL,
  `ssex` char(2) CHARACTER SET utf8 NOT NULL,
  `cno` int(11) NOT NULL,
  `mark` decimal(3,1) NOT NULL,
  `type` char(4) CHARACTER SET utf8 NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `student` VALUES ('9701', '劉建國', '管理工程', '', '4', '82.5', '必修');
INSERT INTO `student` VALUES ('9701', '劉建國', '管理工程', '', '10', '70.0', '必修');
INSERT INTO `student` VALUES ('9701', '劉建國', '管理工程', '', '1', '78.5', '選修');
INSERT INTO `student` VALUES ('9702', '李春', '環境工程', '', '5', '63.0', '必修');
INSERT INTO `student` VALUES ('9702', '李春', '環境工程', '', '10', '58.0', '選修');
INSERT INTO `student` VALUES ('9703', '王天', '生物', '', '5', '48.5', '必修');
INSERT INTO `student` VALUES ('9703', '王天', '生物', '', '2', '86.0', '選修');
INSERT INTO `student` VALUES ('9704', '李華', '電腦', '', '4', '76.0', '必修');
INSERT INTO `student` VALUES ('9704', '李華', '電腦', '', '1', '92.0', '必修');
INSERT INTO `student` VALUES ('9704', '李華', '電腦', '', '2', '89.0', '必修');
INSERT INTO `student` VALUES ('9704', '李華', '電腦', '', '9', '80.0', '必修');
INSERT INTO `student` VALUES ('9704', '李華', '電腦', '', '8', '70.0', '選修');
INSERT INTO `student` VALUES ('9705', '孫慶', '電子工程', '', '8', '79.0', '必修');
INSERT INTO `student` VALUES ('9705', '孫慶', '電子工程', '', '1', '59.0', '必修');
INSERT INTO `student` VALUES ('9705', '孫慶', '電子工程', '', '11', '52.0', '必修');
INSERT INTO `student` VALUES ('9705', '孫慶', '電子工程', '', '6', '68.0', '必修');
INSERT INTO `student` VALUES ('9706', '高偉', '機械工程', '', '13', '93.0', '必修');
INSERT INTO `student` VALUES ('9706', '高偉', '機械工程', '', '12', '88.5', '必修');
INSERT INTO `student` VALUES ('9706', '高偉', '機械工程', '', '1', '78.0', '選修');
INSERT INTO `student` VALUES ('9706', '高偉', '機械工程', '', '10', '76.0', '選修');

CREATE TABLE `teacher` (
  `tno` int(11) NOT NULL,
  `tname` varchar(10) CHARACTER SET utf8 NOT NULL,
  `cno` int(11) NOT NULL,
  `sal` int(11) DEFAULT NULL,
  `dname` char(10) CHARACTER SET utf8 NOT NULL,
  `tsex` char(2) CHARACTER SET utf8 NOT NULL,
  `age` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `teacher` VALUES ('1', '王軍', '4', '800', '數學', '', '32');
INSERT INTO `teacher` VALUES ('2', '李丹', '5', '1200', '生物', '', '54');
INSERT INTO `teacher` VALUES ('3', '王永軍', '1', '900', '電腦', '', '40');
INSERT INTO `teacher` VALUES ('4', '劉小靜', '2', '1200', '電腦', '', '46');
INSERT INTO `teacher` VALUES ('5', '高偉', '8', '2100', '電子工程', '', '39');
INSERT INTO `teacher` VALUES ('6', '李偉', '7', '1200', '機械工程', '', '29');
INSERT INTO `teacher` VALUES ('7', '劉輝', '3', '900', '生物', '', '46');
INSERT INTO `teacher` VALUES ('8', '劉靜', '12', '1300', '經濟管理', '', '28');
INSERT INTO `teacher` VALUES ('9', '李偉', '9', null, '電腦', '', '43');
INSERT INTO `teacher` VALUES ('10', '劉一凱', '13', null, '電腦', '', '33');

 

 

 

 

簡單的二表連接

SELECT tname,dname,cname,ctest from teacher,course WHERE teacher.cno=course.cno
該語句的執行過程實例可以表示這樣: a,系統首先執行from子句,這裡from子句列出有兩個表teacher表和course表,DBMS講計算這兩個表的笛卡爾積,列出這兩個表中行的所以可能組合,形成一個中間表。中間表中的每條記錄包含了兩個表中的所有行。 b,然後系統執行where子句,根據teacher.cno=course.cno關係對中間表進行搜索,去除那些不滿足該關係的記錄。 c,最後系統執行select語句,從執行where子句後得到的中間表的每條記錄中,提取tname,dname,cname,ctest4個欄位的信息作為結果表。     需要強調,表的連接所依據的關係是在where子句中定義的。在實際應用中,用戶要實現表的連接必然要依據一定的關係。     如果不指明連接關係,即不使用where子句。
SELECT tname,dname,cname,ctest from teacher,course

         從結果可以看到,每個教師的信息均與所有課程信息進行了匹配連接。它實際返回連接表中所有數據行的笛卡爾積,其結果集合中的數據行數等於第一個表中符合查詢條件的數據行乘以第二個表中符合查詢條件的數據行數,即10X11=110條記錄。     採用join關鍵字建立連接         也可以在from子句中,通過連接關鍵字實現表的連接,這樣有助於將連接操作與where的搜索條件區分開來。
SELECT COLUMN from join_table join_type join_table on (join_condition)
    join_type為連接類型,可分為4種:自然連接,內連接,外連接和交叉連接。     自連接 自連接是指表與其自身進行連接,這需要使用表別名。 查詢成績中存在不及格課程的學生的姓名,所在系,所有的課程及成績信息
SELECT s.sname,s.dname,s.cno,s.mark
from student s
where s.mark<60
無法得到想要結果    
SELECT s.sname,s.dname,s.cno,s.mark
from student s
where s.sno in(SELECT DISTINCT s.sno from student s where s.mark<60)
得到想要結果    
SELECT DISTINCT s.sname,s.dname,s.cno,s.mark
from student s,student s2
where s.sno=s2.sno
and s2.mark<60
from子句中的兩個表實際上都是表student。為了獨立地使用它們,採用表別名方法。  
SELECT s.sname,s.dname,s.cno,s.mark
from student s,student s2
where s.sno=s2.sno
and s2.mark<60
系統首先執行from子句,將student表S1與它自身S2的笛卡爾積,作為中間表。 實際上,該中間表的每一條記錄包含兩部分信息,一部分是S1的記錄,一部分是S2的記錄。而後執行where子句,在中間表中,搜索S2中成績低於60的學生的記錄,同時要求記錄中S1與S2是同一個學生的記錄即學號相同。最後執行select語句,從中間表獲取S1中相應的信息作為結果表。   當執行where子句,從中間表中逐條搜索S2中成績低於60的學生的記錄時,由於孫慶有兩門課程不及格,所以對每門不及格的記錄都滿足搜索條件,因此導致從S1得到的信息中出現了重覆的記錄。   簡單來說,中間表是沒有重覆記錄的,但是S1部分欄位是有重覆的,而結果集提取的只是S1部分的欄位,因此就有可能有重覆記錄。   一般情況,自連接也可以使用子查詢的方式實現。    
SELECT DISTINCT s.sname,s.dname,s.cno,s.mark
from student s,student s2
where s.sno=s2.sno
and s.mark<60
      自然連接 它將表中具有相同名稱的列自動進行記錄匹配,自然連接不必指定任何同等連接條件。 自然連接自動判斷相同名稱的列,而後形成匹配。缺點是,雖然可以指定查詢結果包括哪些列,但是不能人為地指定哪些列被匹配。另外,自然連接的一個特點是連接後的結果表中匹配的列只有一個。如上,在自然連接後的表中只有一列C。     從student表和teacher表中查詢學生姓名,所在系,所修的本系教師開設的課程的課程號以及開課教師姓名。這時候就採用natural join對兩個表進行自然連接。
SELECT sname,dname,cno,tname
from student NATURAL join teacher
等價
SELECT sname,s.dname,s.cno,tname
from student s, teacher t
where s.dname=t.dname
and s.cno=t.cno

 

事實上,使用基於where子句的等值連接要比使用natural join運算符進行自然連接要靈活的多。 正如前面介紹的,使用natural join運算符自動判斷出具有相同名稱的列,而後形成匹配,不能人為地指定哪些列被匹配。當自然連接student和teacher表時,CNO和dname列同時被匹配,而不能只匹配一列。       外連接 不管是內連接還是帶where子句的多表查詢,都組合自多個表,並生成結果表。換句話說,如果任何一個源表中的行在另一個源表中沒有匹配,DBMS將把該行放在最後的結果表中。   而外連接告訴ODBC生成的結果表,不僅包含符合條件的行,而且還包含左表(左外連接時),右表(右外連接時)或兩個邊接表(全外連接)中所有的數據行。     SQL的外連接共有三種類型:左外連接,右外連接,全外連接。   1,左外連接   左外連接,left outer join ,告訴DBMS生成的結果表中,除了包括匹配行外,還包括join關鍵字(from子句中)左邊表的不匹配行。 左外連接實際可以表示為: 左外連接=內連接+左邊表中失配的元組。 其中,缺少的右邊表中的屬性值用null表示。如下:
SELECT s.sno,sname,s.cno,cname,ctest,mark
from student s LEFT JOIN course c
on s.cno=c.cno
ORDER BY sname
        右外連接   外連接,right outer join ,告訴DBMS生成的結果表中,除了包括匹配行外,還包括join關鍵字(from子句中)邊表的不匹配行。 外連接實際可以表示為: 外連接=內連接+邊表中失配的元組。 其中,缺少的左邊表中的屬性值用null表示。如下:
SELECT s.sno,sname,s.cno,cname,ctest,mark
from student s RIGHT JOIN course c
on s.cno=c.cno
ORDER BY sname<

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這篇是關於網路請求的,結合公司的實際情況編寫,如果有不同意見歡迎留言共同討論。 iOS在9.0之後徹底放棄了NSURLConnection,現在已經改用了NSURLSession進行網路請求。一般現在網路請求也都是使用AFNetworking。下麵就把我自己關於afn和系統的api使用寫下來。 一.
  • 經測試發現,如果EditText預先有內容,游標自然會在文字的末尾 。 但是如果預先內容為空,然後設置好內容,這種情況下游標自然會在文字的開頭,所以這種情況下可以這樣做讓游標位於末尾:editText.setText("0");editText.requestFocus(); //這是關鍵
  • 前言:23種軟體設計模式中的觀察者模式,也是在軟體開發中,挺常用的一種設計模式。而在蘋果開發中,蘋果Cocoa框架已經給我們實現了這個設 計模式,那就是通知和KVO(Key-Value Observing),本篇博文將會先講解通知和KVO的常用方法和使用示例,然後講解觀察者模式以及對觀察者模式的實現
  • 問題 處理表單的時候,一定會碰到的就是輸入控制項被鍵盤遮住的問題,如圖: 實例 左邊是普通表單,中間是2B表單,右邊是文藝表單. 分析 處理這種問題無非就是2個步驟: 鍵盤彈出時,縮小UITableView的frame 滾動UITableView,讓當前輸入的控制項可見 代碼寫出來就是這幾步 捕獲鍵盤事
  • JSON text did not start with array or object and option to allow fragments not set. === AFN使用報錯: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text
  • UITableView可以算是使用頻率最高的組件之一的,在開發過程中經常需要展示一些簡單的信息列表常見列表佈局 如圖,很多頁面其實就是這種展示結果,通常需要imageView,textLabel,detailTextlabel,而UITableViewCell本身提供了方便的自動佈局(當有圖片和沒圖
  • 寫了兩篇《MySQL入門》以後我發現,寫書的人還是都挺有本事的,起碼人家知道怎麼編排自己想講的知識點,我實在是不知道該先說那裡後說哪裡,那我就想到什麼講什麼吧。 一 寫SQL 其實我是不想寫有關SQL的部分的,因為這個部分其實很簡單,基本上大學只要好好聽聽資料庫概論這門課基本上都能寫滿足功能的SQL
  • 今天說一下MySQL的主從複製如何做到! 準備工作: 1.兩個虛擬機:我這裡用的是CentOS5.5,IP地址分別是192.168.1.101 和192.168.1.105; 101做主伺服器,105做從伺服器(都已經安裝相同版本的Mysql); 2.本機環境:Apache+PHP+MySQL 好了
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...