在我久遠的大學時代,當時應該是大三吧,在某家通信公司做實習生,就是給一個上司做資料,資料方面的資料,我們五個人給他一個人提供報表,我們呢,就是分不同方向,将十幾個表格中的資料彙總起來,形成PPT然後給上司去開會使用。
當時是碰到這樣一個問題,就是在一個表格中比對另外一個表格的資料,然後找到表格1 中有的 ,将表格2中的資料寫在表格1 的最後一列,大概的數學模型是這樣:
表格1中的資料:
表格2中的資料:
目的是希望得到這樣的效果:
當然,真實情況資料比這個要多的多,也更加的複雜,這裡隻是一個簡單的數學模型,由于剛接觸工作,對表格也不是很熟悉,自己研究了半天,各種複制,排序,但是就是得不到這樣的結果,後來去請教了一位老員工,他給我說這樣用VLPPKUP啊,當時說實話, 我連這幾個字母都沒聽清楚,後來又請教了一下,自己也上網搜了一下資料,才将這個東西給做出來。雖然現在已經忘記具體怎麼樣操作,但是一直記得excel中有這個功能,直到後來工作使用資料庫後,才發現,這個用關聯做起來真的是無比簡單。
我們先建立表
create table t1 (sno int,sname char(100),course char(100));--建立學生選課表create table t2 (course char(100),tname char(100));--建立教師表
可以看到表已經建立 ,然後我們插入資料
insert into t1(sno,sname,course) values (1001 ,'張三' ,'國文' );insert into t1(sno,sname,course) values (1001 ,'張三' ,'數學' );insert into t1(sno,sname,course) values (1001 ,'張三' ,'英語' );insert into t1(sno,sname,course) values (1004 ,'李四' ,'國文' );insert into t1(sno,sname,course) values (1005 ,'王二麻子' ,'英語' );insert into t2(course,tname) values ('國文','張老師');insert into t2(course,tname) values ('數學','王老師');insert into t2(course,tname) values ('英語','孫老師');
可以看到兩張表都已經有資料,接下來我們進行一個叫做内關聯的操作(inner join ):
select t1.sno,t1.sname,t1.course,t2.tname from t1 inner join t2 on t1.course=t2.course;
可以看到已經得到我們想要的資料了,這個代碼的前提是教師表中必須包含所有的課程,假如有一個學生選了一門還沒有招到教師的課程,也就是教師表中不存在這個課程,那麼,這個代碼會執行出來怎樣的結果呢?
我們先在學生表中寫入一個新學生 王五,選擇了教師表中沒有的化學課程,雖然我不喜歡化學。
insert into t1(sno,sname,course) values (1006 ,'王五' ,'化學' );
可以看到,王五已經被寫入。接下來我們運作代碼
可以看到,王五這個學生消失了,因為在教師表中不存在化學,是以查詢出來的結果沒有被顯示,這種隻保留符合關聯條件的資料,也就是 表1 的課程等于表2 課程的關聯方式,我們叫做内關聯。
這時候,肯定就有人問了,有沒有一種方法,可以保留學生表的所有資料,那肯定是有的,有内關聯,自然就有外關聯(outer join ),外關聯分為左外關聯和右外關聯,根據你想要保留左邊表的全部資料還是想要保留右邊表的所有資料,可以進行适當的選擇,當然,在工作中我們統一使用的是左外關聯,保持代碼的一緻性。
select t1.sno,t1.sname,t1.course,t2.tname from t1 left join t2 on t1.course=t2.course;
寫代碼時,通常會省略 outer。
根據查詢結果,可以看到我們的王同學又回來了,這時候,我們看到王五同學的化學老師名字為(NULL),這裡的null代表的就是空,就是沒有值得意思,顯然,這樣看着不是很明了。是以我們可以利用一個在資料庫中非常常用的函數,空值轉換函數 :ifnull(字段,轉換後的值) 這個函數的作用就是将字段裡面的空值轉換為你所指定的值,可以是其他字段,也可以是常量。
select t1.sno,t1.sname,t1.course,ifnull(t2.tname ,'未找到老師')from t1 left join t2 on t1.course=t2.course;
ps:這裡的ifnull()隻是MySQL的空值轉換函數,在oracle是nvl(),在hana是isnull(),其他資料庫都大同小異,所起的作用是一樣的。
還有一種極端的情況,就是某位教師教的課程很爛,以至于無人挑選,但是還是想把它顯示在表格中以示存在,就是保留兩邊所有的資料,這時候就需要用到全外關聯(full join)
先給教師表插入一個無人問津的教師;
insert into t2(course,tname) values ('法語','趙老師');
可以看到,資料已經被插入,然後運作如下代碼:
select t1.sno,t1.sname,t1.course,ifnull(t2.tname ,'未找到老師')from t1 FULL JOIN t2 on t1.course=t2.course;
這裡我使用的是MYSQL資料庫,mysql是沒有全外連接配接這個概念的,但是可以靠其他方法來實作。這個代碼在oracle資料庫中可以運作,大家可以自行實驗,但是在工作中,這種情況非常少見,大部分時候用左外關聯,因為關聯通常是将事實表和次元表進行關聯。
有一點沒有講到,on後面的内容就是關聯條件,也是兩張表之間連接配接的橋梁。
總結一下今天的内容:
1.内關聯:inner join :隻保留符合關聯條件的資料
2.外關聯:outer join :保留符合關聯條件的資料和所選擇的一側全部資料
其中全外關聯屬于外關聯的一種
3.空值轉換函數: ifnull() ,nvl() ,isnull() :可以将空值轉換為特定的值
剛開始編寫文章,很多地方都有不足,希望以後可以為大家貢獻出更好的文章,謝謝大家!
ps:還沒有講解如何安裝資料庫軟體,我會在公衆号的菜單欄中添加了安裝教程供大家安裝,謝謝
,碰到安裝上的問題也可以給作者發消息或者留言~~
感覺還不錯的話,點下在看鼓勵一下作者吧