關於MySQL中的自聯結的通俗理解
- 前言:最近在通過SQL必知必會這本書學習MySQL的基本使用,在學習中也或多或少遇到了點問題,我也正好分享給大家,我的這篇部落格用到的所有表格的程式碼都是來自SQL必知必會的官方下載地址,但是其理解都是自己的原創沒有任何抄襲,SQL必知必會的程式碼有興趣的朋友可以前去下載。
一、基本概念
(一) SQL的概述
SQL,英文全稱叫Structured Query Language,是結構化查詢語言的意思,結構化查詢語言是高階的非過程化程式語言,允許使用者在高層資料結構上工作。它不要求使用者指定對資料的存放方法,也不需要使用者瞭解具體的資料存放方式,所以具有完全不同底層結構的不同資料庫系統, 可以使用相同的結構化查詢語言作為資料輸入與管理的介面。結構化查詢語言語句可以巢狀,這使它具有極大的靈活性和強大的功能。(摘自百度百科)
(二) MySQL的概述
MySQL是一個關係型資料庫管理系統,由瑞典MySQL AB 公司開發,目前屬於 Oracle 旗下產品。MySQL 是最流行的關係型資料庫管理系統之一,在 WEB 應用方面,MySQL是最好的 RDBMS (Relational Database Management System,關聯式資料庫管理系統) 應用軟體之一。(摘自百度百科)
(三) 聯結和自聯結
聯結:其實聯結的意思很容易理解,就是將兩個表的列結合到一起,形成一個新的表,那麼此時就是說兩個表進行了聯結。因為一個表的資料可能很有限,為了能夠獲得更多的資料並且將這些列放在一起,那麼此時就需要聯結。聯結一般是需要有聯結欄位的。
自聯結:自聯結字面的意思就是,自己和自己聯結。此時聯結所用到的表只有一張,此時我們可以把自聯結想象成兩張一模一樣的表在進行聯結。
二、自聯結的心得體會
自聯結的原理解釋和可能出現的問題
1.自聯結的原理解釋,為此我準備了兩張一模一樣的表格,進行模擬自聯結的進行
表格演示
程式碼演示
1 -- 以下是該表的欄位資訊 2 CREATE TABLE `customers` ( 3 `cust_id` CHAR ( 10 ) NOT NULL, 4 `cust_name` CHAR ( 50 ) NOT NULL, 5 `cust_address` CHAR ( 50 ) DEFAULT NULL, 6 `cust_city` CHAR ( 50 ) DEFAULT NULL, 7 `cust_state` CHAR ( 5 ) DEFAULT NULL, 8 `cust_zip` CHAR ( 10 ) DEFAULT NULL, 9 `cust_country` CHAR ( 50 ) DEFAULT NULL, 10 `cust_contact` CHAR ( 50 ) DEFAULT NULL, 11 `cust_email` CHAR ( 255 ) DEFAULT NULL, 12 PRIMARY KEY ( `cust_id` ) 13 ) ENGINE = INNODB DEFAULT CHARSET = utf8
1)自聯結的一張表的程式碼演示和查詢結果
程式碼演示
1 -- 以下的程式碼是在同一張表上進行的真正的自聯結 2 select c1.cust_name,c1.cust_country 3 from customers c1,customers c2 4 where c1.cust_country = c2.cust_country and c2.cust_contact = 'Michelle Green';
查詢結果
2)模擬自聯結的兩張表進行聯結的程式碼演示和查詢結果
程式碼演示
1 -- 以下程式碼裡面是兩個一樣的表,另外一個表叫customers_copy是對原表的備份 2 select c1.cust_name,c1.cust_country 3 from customers c1,customers_copy c2 4 where c1.cust_country = c2.cust_country and c2.cust_contact = 'Michelle Green';
查詢結果
3)總結
我們會發現查詢的結果是一樣的,那麼我們就可以簡單地認為自聯結查詢和兩張一樣的表進行聯結的效果等同,但是其實我不瞭解其底層實現,所以也不敢說他們肯定是一樣,我只能說可能效果上是相似的。
2.自聯結可能出現的問題
1)自聯結的沒有充分過濾
A 自聯結沒有充分過濾條件的程式碼演示
1 -- 以下僅僅使用了cust_name這一包含重複資訊的欄位進行了聯結,但是沒有再多加條件進行二次過濾,可能出現笛卡爾積的類似錯誤,得到錯誤的資訊 2 select o1.cust_name,o1.cust_contact,o1.cust_id 3 from customers o1, customers o2 4 where o1.cust_name = o2.cust_name;
演示結果,出現了四個Fun4All,其實我們的原表就只有兩個Fun4All這樣的結果就是出現了垃圾資訊
B 自聯結進行了過濾的程式碼演示
1 -- 以下的程式碼也是使用了cust_name作為聯結欄位,但是加了一個過濾條件,那麼得到的結果就更為正確 2 select o1.cust_name,o1.cust_contact,o1.cust_id 3 from customers o1, customers o2 4 where o1.cust_name = o2.cust_name and o2.cust_contact = 'Jim Jones';
演示結果,新增了雙重過濾之後,表格的結果就更加正確,沒有更多的垃圾或者錯誤的資訊
2)總結
如果想要對單個表格進行查詢,那麼自聯結其實比自查詢的效率要高很多,當我們要查詢單個表中的資料的時候,查詢又較為複雜的時候,那麼自聯結就能夠派上用場了,但是要注意自聯結的過濾條件和欄位的選擇。