在解釋為什麼使用 “外部連接” 之前,先來看一個記錄。 (如下:)
針對表中的張三沒有所屬的部門編號,我們暫且將他歸類為 「臨時工」 ,沒有固定的部門編制。
介於如此的場景,那麼問題就出現了。當我們想要查詢每位員工和他所屬的部門的名稱時,在使用內連結的情況下,因為我們的連結條件是` 「員工表」 的「部門編號」 = “部門表” 的「部門編號」 ,就會將「張三」 漏掉。雖然說 “張三” 沒有 “部門編號” ,但是他作為 “臨時工” 也是公司的一員, 所以要引入外連接的語法才能解決這個問題,否則就會丟失一些符合邏輯的數據。
外連接與內連接的區別:
內連接的結果接中只會出現符合連接條件的記錄,不符合連接條件的記錄是絕對不會出現在結果集裡面的。
無論是否滿足資料連接條件,外部連接都會以特殊的方式顯示在結果集中。 (就例如上文提到的查詢員工部門標號信息,因為“張三” 沒有部門編號,如果使用內連接,則“張三” 就不符合“連接條件”,也就不會出現在結果集裡面;換做「外連接」就不會漏掉了。)
外連接例句如下
SELECT e.empno, e.ename, d.dname FROM t_emp e LEFT JOIN t_dept d ON e.deptno = d.deptno; -- 在连接的时候仍然是链接 "员工表" 与 "部门表" ,只不过连接关键字由 "JOIN" 变成了 "LEFT JOIN" (下文再为大家详细解释) -- 两张表的连接条件还是使用 "ON" 关键字去连接的 , 连接条件依然是 "员工表" 的 "部门编号" = "部门表" 的 "部门编号" -- LEFT JOIN 为 "外连接" 的 "左外连接" ;(在 "外连接" 中,是分为 "左外连接" 与 "右外连接" 的) -- 在该SQL语句中 "LEFT JOIN" 左右各有数据表 "t_emp e" 与 "t_dept d" -- 所以这里的 "左连接" 的意思就是:保留 左表 的所有记录,然后与 右表 去连接,如果 右表 有符合条件的记录,则正常连接即可; -- 如果 右表 没有符合条件的连接记录, 右表 则展示 "NULL" 值与 "左表" 去匹配
「左外連接」是指連接操作時,保留左邊表的所有記錄並與右邊表做連接。左表將與右表連接,如果右表中存在符合條件的記錄;如果右表中不存在符合條件的記錄,則用「NULL」連接左表。
區別於“左連接” 的就是“右連接”,“右連接” 與“左連接” 相反,是保留右表的所有記錄與左表的符合條件的記錄進行連接;同樣的,如果左表沒有符合條件的記錄,就用「NULL」 與右表連接。
右邊連接SQL 語句範例:
SELECT e.empno, e.ename, d.dname FROM t_dept d RIGHT JOIN t_emp e ON e.deptno = d.deptno; -- 这里有个需要注意的地方,就是相较于上文中的 "左连接" ,这里的 "右连接" 左右两张的表的位置做了调换
#在這裡,大家可以看到,仍然可以查出來“張三” 的沒有“部門編號”的記錄。所以說 “左連接” 與 “右連接” 的差別並不是很大。
查詢每個部門的名稱和部門的人數?
這題看似簡單,但是裡面存在著兩個難點,而且也存在容易出錯的地方,詳見下文 SQL 語句範例,與示意圖。
SELECT d.deptno, d.dname, COUNT(*) FROM t_dept d LEFT JOIN t_emp e ON d.deptno = e.deptno GROUP BY d.deptno;
OK,問題就在這裡開始出現了。
大家注意到這裡的「40」 - 「OPERATIONS」 部門,這個部門其實是沒有人的,也就是人數為「0」 ,但是奇怪的是,這裡進行統計的時候,卻出現了統計人數「1」 ,這是為什麼呢?
這是因為我們在使用分組的時候,用的是「左連接」 ,保留了左表的所有的數據,所以就按照左表的“deptno” 進行分組。 (因為是保留了左表的記錄,所以分組也需要按照左表進行分組。接下來的關鍵在於“COUNT(*)”,它會統計所有有效記錄的數量。所以當左表“t_dept” 的所有記錄與右表“t_emp” 進行連接的時候,右表會使用"NULL"值與左表“t_dept” 連接,連接完之後就是一條有效的記錄,如此既然是有效記錄,那麼“COUNT(*)”統計到的結果就是「1」。
所以,如此統計到40 部門的統計結果為「1」 ,也是情有可原的,但是這個結果並不是我們想要的,要怎麼去解決呢?參考下方的SQL 語句。
SELECT d.deptno, d.dname, COUNT(e.deptno) FROM t_dept d LEFT JOIN t_emp e ON d.deptno = e.deptno GROUP BY d.deptno;
這個SQL 語句還是非常不錯的,有非常多的細節與未考慮到的情況,只有真正寫一遍的時候才能會注意到這些攻擊。
檢索部門名稱和人數,對於沒有部門的員工,用「NULL」代替部門名稱。(這裡其實就是指的"張三")
可能這裡會覺得剛剛使用的是"左外連接" 保留的部門表中所有的記錄,這裡直接換成"右" 外連接不就行了麼?其實.. .沒那麼簡單。
這個練習的SQL 語句需要使用到"UNION"關鍵字去實現,利用"UNION" 關鍵字將多個查詢語句的結果集進行並集的合併處理(排除重複內容)。
"UNION"关键字 在 SQL 语句中的用法如下:
(SQL查询语句) UNION (SQL查询语句) -- 如果存在多条查询语句的话,可以继续使用 UNION 关键字 连接
PS:这里需要注意一下,“UNION” 合并多少个结果集其实无所谓,关键是这些结果集的字段数量和字段的名称必须要相同 。如果说第一个 SQL 查询语句返回的是 10个 字段,第二个返回的是 2个字段 ,这种情况是完全没办法合并的。
(SELECT d.deptno, d.dname, COUNT(e.deptno) FROM t_dept d LEFT JOIN t_emp e ON d.deptno = e.deptno GROUP BY d.deptno) UNION (SELECT d.deptno, d.dname, COUNT(*) FROM t_dept d RIGHT JOIN t_emp e ON d.deptno = e.deptno GROUP BY d.deptno); -- 第一个查询语句,得到的结果集是各个部门的人数。 -- 第二个查询语句,得到的结果集是隶属于各个部门的人数,但是因为 "张三" 是一个没有部门所属的 "临时工" -- 所以两个查询语句的结果集合并之下没救如下图所示。
以上是MySQL中資料表的外接連線怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!