今天是劉小愛自學Java的第64天。
感謝你的觀看,謝謝你。
話不多說,繼續開始資料庫的學習:
昨天學習了多表設計,事實上我們所需要的數據,通常會來自多張表。
那麼如何使用sql語句一次性查詢多張表的數據?
這是我們應該去考慮的問題,為了解決這個問題,今天繼續學習多表查詢。
一、笛卡爾積與內連接
萬萬沒有想到,學個資料庫竟然還能接觸到笛卡爾積?後面不會學著學著還會出現牛頓吧……
牛頓、拉格朗日、泰勒、傅立葉……簡直就是大學噩夢般的存在。
現在有兩張表:部門表、成員表。
那如何查詢出一個結果既顯示成員又顯示部門呢?
就需要引入笛卡爾積的概念:
格式:select * from member,department;
查出來的數據就相當於成員表與部門表的乘積。
也就是將成員表裡的每一條數據都和部門表中的每一條匹配連接。
成員表一共有7條數據部門表一共有4條數據那根據笛卡爾積查詢出來的數據一共4*7=28條那麼現在問題來了:這就變成排列組合了,查詢到的結果冗餘。如何避免結果冗餘?
將這兩張表相同的地方作為查詢條件:
①隱式內連接
select * from+表A+表B+where+A與B相交的部分;
②顯示內連接
select * from+表A+inner join+表B+on+A與B相交的部分;
inner join,也就是內連接的意思。on,在這裡就相當於where,後面接查詢條件,其中on也可以替換成where。那這兩者有沒有區別呢?
基本沒區別,就只是語法不一樣,個人覺得:
第一種語法更好理解。第二種語法看上去更加地專業。二、三種外連接
外連接又分為左外連接和右外連接。
左外連接:顯示左表的全部記錄以及右邊符合連接條件的記錄。右外連接:原理同上,只不過表相反。
①左外連接
select * from+表A+left outer join+表B+on+A與B相交的部分;
left,左邊outerjoin:外連接也就是左邊表A全部的數據,同時加上表B中與之相交的部分。
②右外連接
select * from+表A+right outer join+表B+on+A與B相交的部分;
right ,右邊也就是右邊表B全部的數據,同時加上表A中與之相交的部分。
③全外連接
select * from+表A+full outer join+表B+on+A與B相交的部分;
全外連接裡的關鍵單詞為full。
但是這個語法在MySQL資料庫中不支持,Oracle資料庫才支持。那MySQL中是如何辦的?
就是將左外連接和右外連接結合起來了。
三、四種連接方式圖解
表A與表B,其中它們相互重合的部分為C。
四種連接方式圖解如下:
①內連接
就相當於C。
將這兩張表重合的部分查詢出來。
②左外連接
就相當於A+C。
左邊的表加上另一張表與之相交的部分。
③右外連接
就相當於C+B。
右邊的表加上另一張表與之相交的部分。
④全外連接
就相當於A+B+C。
兩張表的數據相結合,其中相關聯的部分要結合起來。在MySQL資料庫中全外連接是如何表示的?
全外連接=左外連接+右外連接;
所以多了一個C,那麼就要去重。
語法格式也就是左外連接和右外連接相加。
union :去掉重複的數據。union all :不去掉重複的數據。其中注意第一條查詢語句不用加分號。四、關聯子查詢
現有一個需求:要查詢出年齡最小的部門成員信息。
①常規方法
先查詢出最小的年齡是多少(通過聚合函數)
再根據查詢到的最小年齡查詢對應的成員信息
這樣做自然是能解決需求的,但是有一個問題:
查詢要訪問資料庫兩次,並且第二次查詢需要等到第一次的查詢結果出來後才能寫sql語句。②子查詢
等於是將常規方法中的兩步結合成一步了。
語法:A查詢語句作為B查詢語句的條件,那麼A查詢稱之為子查詢,B查詢稱之為主查詢。
子查詢都要寫在 () 裡,且執行要先於主查詢。
③all的用法
前面的兩個方案中都是使用了聚合函數min()來找出最小的年齡是多少。
而all也能達到這樣的目的,語法為:
age<=all(select age from member)。
翻譯過來就是:年齡小於或等於從member表中查到的所有年齡,也就是最小年齡了。
五、in、any和some的用法
昨天程式設計師表和項目表的多對多表關係。
看中間表
第一行:劉小愛開發微軟,money為10000;第二行:劉小愛開發蘋果,money為20000;……這樣看下來就一目了然。現有一個需求:
查詢money大於10000的程式設計師信息。
分析:
第一步:先從中間表coder_project中查詢出money大於10000的coder_id;
第二步:根據查詢到的coder_id查詢對應的coder信息。
學了子查詢,可以將這兩步並為一步。
子查詢查出coder_id,主查詢再查出程式設計師信息。
①In的使用
in就是表示包含子查詢查出的數據。
當子查詢結果只有一個時,可以用=,也可以用in。當子查詢結果有多個時,不可以用=,只能用in。所以說in的使用其實包含了=。
②any的使用
雖然子查詢結果有多個,我就是要用=,怎麼辦?
就可以用any,any表示任意的意思,也就是=子查詢查出的任意一個數據。
③some的使用
同any一樣的道理:也就是=子查詢查出的一些數據。some作用和any一樣。
六、as的使用
需求: 查詢money大於10000的程式設計師信息和對應的money。
思路分析:
第一步:我們從中間表coder_project中可以找到滿足條件的coder_id和money,結果就是一張新的臨時表,取名temp。
第二步:根據code_id(臨時表)找出所有對應的程式設計師信息(coder表)和money(臨時表)。
①思路分析
第一步:
將查詢到的結果作為了一張臨時表temp,但是這張表本身是不存在的,我們沒法直接在第二步中用,會報錯。
temp表其實就是中間表coder_project中的一部分滿足條件的數據。
第二步:
我們需要對應程式設計師的所有信息(也就是coder.*)我們需要temp表中的money從temp表、coder表中查詢coder表中的id和temp表中的coder_id相同,也就是內連接相等的部分。②as定義臨時表
利用子查詢的思路,將第一步的結果作為子查詢,然後給它起一個別名,也就是temp表,這樣就能直接使用了。
思路捋清晰了,as定義臨時表也就很好懂了。
最後
給這兩天的學習做一個總結
謝謝你的觀看。
如果可以的話,麻煩幫忙點個讚,謝謝你