您好,登錄后才能下訂單哦!
這篇文章主要介紹“Mariadb怎么實現多表連接查詢”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Mariadb怎么實現多表連接查詢”文章能幫助大家解決問題。
因為我們使用的是關系型數據庫,每張表表示的都是獨立的單元(對象),而該單元(對象)所涉及到的其他信息通常都存儲在其他表中,例如:
MariaDB [world]> DESC city; +-------------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(35) | NO | | | | | CountryCode | char(3) | NO | MUL | | | | District | char(20) | NO | | | | | Population | int(11) | NO | | 0 | | +-------------+----------+------+-----+---------+----------------+ 5 rows in set (0.61 sec) MariaDB [world]> DESC countrylanguage; +-------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+---------------+------+-----+---------+-------+ | CountryCode | char(3) | NO | PRI | | | | Language | char(30) | NO | PRI | | | | IsOfficial | enum('T','F') | NO | | F | | | Percentage | float(4,1) | NO | | 0.0 | | +-------------+---------------+------+-----+---------+-------+ 4 rows in set (0.06 sec)
比如其上兩張表,我們想知道某一城市所使用的語言,就可以分為兩個步驟:
1.在City表中查詢該城市的CountryCode。
2.使用查詢到的這個CountryCode在CountryLanguage表中查詢該國家所使用的語言。
雖然,可以分兩步完成,但是,需要兩次查詢和兩次傳輸,在帶寬和性能的對比下,我們更希望讓Mysql(MariaDB)來幫助我們完成這件事不是嗎?
連接(JOIN):也叫連結,是指將兩張表按照一定規則連成一張表,將兩張表中不同的數據(行)連成一行來看待。
又可以將連接分為如下幾類:
內連接
外連接
交叉連接
在連接查詢中,一個列可能出現在多張表中,為了避免引起歧義,通常在列名前面加上表名或表別名作為前綴(例:s.sid、x.sid)—使用表別名作為前綴,可以使得SQL代碼較短,使用的內存更少(例:stu s,xuanke as x)。
內連接
內連接語法如下:
SELECT tb1_name.column,tb2_name.column FROM tb1 INNER JOIN tb2 ON 約束條件; SELECT tb1_name.column,tb2_name.column FROM tb1,tb2 WHERE 約束條件;
查詢每一個城市可能使用的語言有哪些:
MariaDB [world]> SELECT Name,District,Language FROM city,countrylanguage WHERE city.CountryCode = countrylanguage.CountryCode LIMIT 10; +----------+----------+------------+ | Name | District | Language | +----------+----------+------------+ | Kabul | Kabol | Balochi | | Kabul | Kabol | Dari | | Kabul | Kabol | Pashto | | Kabul | Kabol | Turkmenian | | Kabul | Kabol | Uzbek | | Qandahar | Qandahar | Balochi | | Qandahar | Qandahar | Dari | | Qandahar | Qandahar | Pashto | | Qandahar | Qandahar | Turkmenian | | Qandahar | Qandahar | Uzbek | +----------+----------+------------+ 10 rows in set (0.00 sec)
內連接是怎樣工作的
我們來看一下,這些數據是怎么連接起來的,具體可以看如下這張圖(放大看):
所以所謂內連接,就是僅將多表中符合條件的行進行連接且返回結果。
比如這樣,就將三張表連接了起來:
MariaDB [world]> SELECT * FROM city INNER JOIN countrylanguage INNER JOIN country ON city.CountryCode = countrylanguage.CountryCode AND city.CountryCode = country.Code WHERE city.Name='Kabul'\G; *************************** 1. row *************************** ID: 1 Name: Kabul CountryCode: AFG District: Kabol Population: 1780000 CountryCode: AFG Language: Balochi IsOfficial: F Percentage: 0.9 Code: AFG Name: Afghanistan Continent: Asia Region: Southern and Central Asia SurfaceArea: 652090.00 IndepYear: 1919 Population: 22720000 LifeExpectancy: 45.9 GNP: 5976.00 GNPOld: NULL LocalName: Afganistan/Afqanestan GovernmentForm: Islamic Emirate HeadOfState: Mohammad Omar Capital: 1 Code2: AF ....僅截取了第一條記錄 5 rows in set (0.01 sec)
這里比較推薦SQL的標準寫法,也就是如下格式:
SELECT tb1_name.column,tb2_name.column FROM tb1 INNER JOIN tb2 ON 約束條件;
為什么呢?因為在ON子句后還可以跟WHERE子句多連接出來的表進行過濾呀,且此語法結構更清晰不是嗎?
外連接
使用內連接會將多表中符合條件的行連接到一起,而不符合條件的行則忽略,而外連接則會將一些不符合條件的行也輸出出來。
例如,我們有如下數據:
MariaDB [world]> SELECT * FROM user; +----+-------+----------+---------------------+--------+ | id | name | password | regtime | deptid | +----+-------+----------+---------------------+--------+ | 1 | test | test | 2018-03-05 17:25:26 | 1 | | 2 | test1 | test1 | 2018-03-05 17:25:26 | 1 | | 3 | lucy | lucy | 2018-03-05 17:25:26 | 2 | | 4 | mars | mars | 2018-03-05 17:25:26 | 3 | | 5 | mark | mark | 2018-03-05 17:26:05 | NULL | +----+-------+----------+---------------------+--------+ 5 rows in set (0.01 sec) MariaDB [world]> SELECT * FROM department; +----+------------+---------+----------+ | id | name | comment | adminids | +----+------------+---------+----------+ | 1 | Sales | NULL | NULL | | 2 | Tech | NULL | NULL | | 3 | administra | NULL | NULL | | 4 | Secretaria | NULL | NULL | +----+------------+---------+----------+ 4 rows in set (0.01 sec) //其中deptid是用戶所屬部門的編號
我們有如下需求,顯示用戶及用戶所在部門名稱,根據我們上面所說的內連接,我們可以寫出如下語句:
MariaDB [world]> SELECT user.id,user.name,department.name FROM user INNER JOIN department ON user.deptid = department.id; +----+-------+------------+ | id | name | name | +----+-------+------------+ | 1 | test | Sales | | 2 | test1 | Sales | | 3 | lucy | Tech | | 4 | mars | administra | +----+-------+------------+ 4 rows in set (0.14 sec)
但是,結果對嗎?雖說我們的mark先生還沒有被分到任何部門,但是也不能不顯示人家了吧?
這時候,外連接就派上用場了:
在JOIN左面的表叫左表,而在右面的表叫右表
**除將符合條件的行顯示出來,還顯示左表的全部行,而右表的字段拼接過去全為NULL。**如下所示:
MariaDB [world]> SELECT * FROM user LEFT OUTER JOIN department ON user.deptid = department.id; +----+-------+----------+---------------------+--------+------+------------+---------+----------+ | id | name | password | regtime | deptid | id | name | comment | adminids | +----+-------+----------+---------------------+--------+------+------------+---------+----------+ | 1 | test | test | 2018-03-05 17:25:26 | 1 | 1 | Sales | NULL | NULL | | 2 | test1 | test1 | 2018-03-05 17:25:26 | 1 | 1 | Sales | NULL | NULL | | 3 | lucy | lucy | 2018-03-05 17:25:26 | 2 | 2 | Tech | NULL | NULL | | 4 | mars | mars | 2018-03-05 17:25:26 | 3 | 3 | administra | NULL | NULL | | 5 | mark | mark | 2018-03-05 17:26:05 | NULL | NULL | NULL | NULL | NULL | +----+-------+----------+---------------------+--------+------+------------+---------+----------+ 5 rows in set (0.00 sec)
顧名思義,就是顯示右表的所有行,而未符合連接條件的行,左表字段全為NULL,如下所示:
MariaDB [world]> SELECT * FROM user RIGHT OUTER JOIN department ON user.deptid = department.id; +------+-------+----------+---------------------+--------+----+------------+---------+----------+ | id | name | password | regtime | deptid | id | name | comment | adminids | +------+-------+----------+---------------------+--------+----+------------+---------+----------+ | 1 | test | test | 2018-03-05 17:25:26 | 1 | 1 | Sales | NULL | NULL | | 2 | test1 | test1 | 2018-03-05 17:25:26 | 1 | 1 | Sales | NULL | NULL | | 3 | lucy | lucy | 2018-03-05 17:25:26 | 2 | 2 | Tech | NULL | NULL | | 4 | mars | mars | 2018-03-05 17:25:26 | 3 | 3 | administra | NULL | NULL | | NULL | NULL | NULL | NULL | NULL | 4 | Secretaria | NULL | NULL | +------+-------+----------+---------------------+--------+----+------------+---------+----------+ 5 rows in set (0.00 sec)
交叉連接與笛卡爾積
當沒有連接條件的表進行連接的結果為笛卡兒積,檢索出的行的數目將是第一個表中的行數乘以第二個表中的行數,如下圖所示:
如果有使用笛卡爾積的必要時,可以使用交叉連接(CROSS JOIN)如下例所示:
MariaDB [world]> SELECT user.Name,department.name FROM user CROSS JOIN department; +-------+------------+ | Name | name | +-------+------------+ | test | Sales | | test | Tech | | test | administra | | test | Secretaria | | test1 | Sales | | test1 | Tech | | test1 | administra | | test1 | Secretaria | | lucy | Sales | | lucy | Tech | | lucy | administra | | lucy | Secretaria | | mars | Sales | | mars | Tech | | mars | administra | | mars | Secretaria | | mark | Sales | | mark | Tech | | mark | administra | | mark | Secretaria | +-------+------------+ 20 rows in set (0.00 sec)
多表連接的條件過濾
當我們的想要過濾多表連接查詢結果時,我們可以將過濾條件放在ON子句或者WHERE子句,ON子句和WHERE子句得到的結果可能會不太一樣。
** 過濾條件放ON子句:使用AND邏輯與操作將過濾條件放在連接條件前或后->在連接前進行條件過濾。** ** 過濾條件放WHERE子句:使用單獨的WHERE子句進行數據過濾->在連接后進行條件過濾。**
對于內連接而言,過濾條件放在ON子句或WHERE子句是相同的,比較推薦在ON子句過濾。
而對于外連接而言,有以下情況參考:
//過濾條件放連接條件前或后 MariaDB [world]> SELECT user.name,department.name FROM user LEFT OUTER JOIN department ON user.name='mars' AND user.deptid = department.id; MariaDB [world]> SELECT user.name,department.name FROM user LEFT OUTER JOIN department ON user.deptid = department.id AND user.name='mars'; +-------+------------+ | name | name | +-------+------------+ | test | NULL | | test1 | NULL | | lucy | NULL | | mars | administra | | mark | NULL | +-------+------------+ 5 rows in set (0.00 sec) //因為ON user.name='mars'會將左表變為一條數據,但AND要求第二個表達式也為真,user.deptid = department.id;這條又僅過濾了mars的deptid和其部門表中對應的id,但左連接又要求左表顯示所有數據,所以右表字段為NULL //過濾條件放WHERE子句,因為是連接后進行過濾,就是說對連接生成的這個新表過濾,所以只會顯示符合條件的這條數據。 MariaDB [world]> SELECT user.name,department.name FROM user LEFT OUTER JOIN department ON user.deptid = department.id WHERE user.name = 'mars'; +------+------------+ | name | name | +------+------------+ | mars | administra | +------+------------+ 1 row in set (0.00 sec)
表的重命名
在多表連接查詢時,通常會對表進行重命名操作,與列的重命名一樣使用AS關鍵字,對表重命名主要是引用表時使用方便。
如下所示,對user表重命名為U,對department重命名為D:
MariaDB [world]> SELECT U.name,D.name FROM user AS U LEFT OUTER JOIN department AS D ON U.deptid = D.id; +-------+------------+ | name | name | +-------+------------+ | test | Sales | | test1 | Sales | | lucy | Tech | | mars | administra | | mark | NULL | +-------+------------+ 5 rows in set (0.01 sec)
多表連接與聚合函數的使用
多表連接查詢說白了就是產生一張臨時的新表,所以使用分組和聚合函數就像平常一樣簡單,參考如下例子:
統計每個部門的人數:
MariaDB [world]> SELECT D.name,COUNT(U.name) FROM user AS U LEFT OUTER JOIN department AS D ON U.deptid = D.id GROUP BY D.name; +------------+---------------+ | name | COUNT(U.name) | +------------+---------------+ | NULL | 1 | | administra | 1 | | Sales | 2 | | Tech | 1 | +------------+---------------+ 4 rows in set (0.00 sec)
統計每個城市所能說的官方語言的數量:
MariaDB [world]> SELECT C.Name,COUNT(CL.Language) FROM city AS C INNER JOIN countrylanguage AS CL ON C.CountryCode = CL.CountryCode AND CL.IsOfficial = 'T' GROUP BY C.Name; +-------------------------+--------------------+ | Name | COUNT(CL.Language) | +-------------------------+--------------------+ | A Coruña (La Coruña) | 1 | | Aachen | 1 | ................................................ | Alicante [Alacant] | 1 | | Aligarh | 1 | +-------------------------+--------------------+
關于“Mariadb怎么實現多表連接查詢”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。