自己对mysql中的Join的理解
生活随笔
收集整理的這篇文章主要介紹了
自己对mysql中的Join的理解
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
注: 本文是我自己的學(xué)習(xí)思路。自己的理解還很淺,而且很有可能是錯(cuò)的。文章只是輔助自己理解。若有看官閱讀了,請(qǐng)指出我的錯(cuò)誤,但請(qǐng)不要侮辱我。
cityjoin表:
+----+-----------+-------------+-----------+------------+
| id | Name????? | CountryCode | District? | Population |
+----+-----------+-------------+-----------+------------+
|? 1 | Shanghai? | CHN???????? | Shanghai? |??? 9696300 |
|? 2 | Peking??? | CHN???????? | Peking??? |??? 7472000 |
|? 3 | Chongqing | CHN???????? | Chongqing |??? 6351600 |
|? 4 | Tianjin?? | CHN???????? | Tianjin?? |??? 5286800 |
|? 5 | Wuhan???? | CHN???????? | Hubei???? |??? 4344600 |
+----+-----------+-------------+-----------+------------+
?
?countryjoin表:
?+------+-------------+---------------+-------------+------------+
| Code | Name??????? | Continent???? | SurfaceArea | Population |
+------+-------------+---------------+-------------+------------+
| ABW? | Aruba?????? | North America |????? 193.00 |???? 103000 |
| AFG? | Afghanistan | Asia????????? |?? 652090.00 |?? 22720000 |
| AGO? | Angola????? | Africa??????? |? 1246700.00 |?? 12878000 |
| AIA? | Anguilla??? | North America |?????? 96.00 |?????? 8000 |
| ALB? | Albania???? | Europe??????? |??? 28748.00 |??? 3401200 |
| CHN? | China?????? | Asia????????? |? 9600000.00 |? 130000000 |
+------+-------------+---------------+-------------+------------+
?
?1. Join
?select cityjoin.id, cityjoin.Name, countryjoin.Name c_Name from cityjoin left join countryjoin on cityjoin.Name=cityjoin.District and countryjoin.Code=cityjoin.CountryCode;
?我們要從 cityjoin 表要選出的記錄(不過(guò)只顯示id和Name)要滿足的條件是
?cityjoin.Name=cityjoin.District
?AND
?countryjoin.Code=cityjoin.CountryCode;
?怎么理解?就是說(shuō)我們把左右兩表作了連接,要顯示的就是city表中的直轄市,并且,這個(gè)直轄市所在的國(guó)家要在countryjoin表中對(duì)應(yīng)起來(lái),最后把完全滿足于這個(gè)條件的左右表需要的記錄返回過(guò)來(lái)。
?
?返回的記錄為:
?+----+-----------+--------+
| id | Name????? | c_Name |
+----+-----------+--------+
|? 1 | Shanghai? | China? |
|? 2 | Peking??? | China? |
|? 3 | Chongqing | China? |
|? 4 | Tianjin?? | China? |
+----+-----------+--------+
上述是最正確的情況,也滿足了需求。現(xiàn)在來(lái)破壞條件。
首先試著在cityjoin加上一條數(shù)據(jù),滿足cityjoin.Name=cityjoin.District,不過(guò)讓這個(gè)直轄市所在的國(guó)家在country表中找不到。
INSERT INTO cityjoin VALUES('SaltLake', 'USA', 'SaltLake', 500000);
此時(shí)的cityjoin表:
+----+-----------+-------------+-----------+------------+
| id | Name????? | CountryCode | District? | Population |
+----+-----------+-------------+-----------+------------+
|? 1 | Shanghai? | CHN???????? | Shanghai? |??? 9696300 |
|? 2 | Peking??? | CHN???????? | Peking??? |??? 7472000 |
|? 3 | Chongqing | CHN???????? | Chongqing |??? 6351600 |
|? 4 | Tianjin?? | CHN???????? | Tianjin?? |??? 5286800 |
|? 5 | Wuhan???? | CHN???????? | Hubei???? |??? 4344600 |
|? 6 | SaltLake? | USA???????? | SaltLake? |???? 500000 |
+----+-----------+-------------+-----------+------------+
然后重新執(zhí)行上面的select語(yǔ)句,結(jié)果仍舊一樣。
+----+-----------+--------+
| id | Name????? | c_Name |
+----+-----------+--------+
|? 1 | Shanghai? | China? |
|? 2 | Peking??? | China? |
|? 3 | Chongqing | China? |
|? 4 | Tianjin?? | China? |
+----+-----------+--------+
新加入的SaltLake,滿足了直轄市的條件,不過(guò)對(duì)應(yīng)的國(guó)家在country那邊是找不到的。所以不予顯示: 考慮我們要列擁有id,Name,c_Name3個(gè)列的表出來(lái),下面全是直轄市。不過(guò)如果我們將SaltLake的東西要顯示出來(lái),那么c_Name這里該顯示什么東西?沒(méi)錯(cuò),就是Null。顯然join不和Null打交道。換而言之,我們用join連接時(shí),左右表中任意可能出現(xiàn)Null的記錄,都不會(huì)被返回。那么如果我想顯示呢?如果想要顯示沒(méi)有對(duì)應(yīng)country的直轄市,left join就派上用場(chǎng)了。
2. Left/Right Join
依然是上面加入SaltLake的表,查詢語(yǔ)句中join換為left join.結(jié)果如下:
+----+-----------+--------+
| id | Name????? | c_Name |
+----+-----------+--------+
|? 1 | Shanghai? | China? |
|? 2 | Peking??? | China? |
|? 3 | Chongqing | China? |
|? 4 | Tianjin?? | China? |
|? 5 | Wuhan???? | NULL?? |
|? 6 | SaltLake? | NULL?? |
+----+-----------+--------+
恩?按照之前的設(shè)想應(yīng)該把直轄市SaltLake加入進(jìn)去,在c_Name顯示NULL才對(duì)。怎么Wuhan也加進(jìn)來(lái)了?
來(lái)看看LEFT JOIN的解釋:
LEFT JOIN 關(guān)鍵字會(huì)從左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中沒(méi)有匹配的行。
這下清楚了,之前的理解是有誤的。我們的join table on 后面的條件是一個(gè)整體,如果分開(kāi)來(lái)看,那就大錯(cuò)特錯(cuò)了。
再試試right join
+------+-----------+-------------+
| id?? | Name????? | c_Name????? |
+------+-----------+-------------+
|??? 1 | Shanghai? | China?????? |
|??? 2 | Peking??? | China?????? |
|??? 3 | Chongqing | China?????? |
|??? 4 | Tianjin?? | China?????? |
| NULL | NULL????? | Aruba?????? |
| NULL | NULL????? | Afghanistan |
| NULL | NULL????? | Angola????? |
| NULL | NULL????? | Anguilla??? |
| NULL | NULL????? | Albania???? |
+------+-----------+-------------+
我們可以總結(jié)出一句話: join是精確篩選,而left/right join則是在精確篩選的基礎(chǔ)之上,將左/右 表的記錄再單獨(dú)塞進(jìn)去,然后在 右/左表的列名下面留NULL。
我們可以用where字句把left join的結(jié)果集進(jìn)行逆向篩選:
?select cityjoin.id, cityjoin.Name, countryjoin.Name c_Name
?from cityjoin
?left join countryjoin
?on cityjoin.Name=cityjoin.District and countryjoin.Code=cityjoin.CountryCode
?where cityjoin.Name=cityjoin.District and countryjoin.Code=cityjoin.CountryCode;
?
結(jié)果如下:
+----+-----------+--------+
| id | Name????? | c_Name |
+----+-----------+--------+
|? 1 | Shanghai? | China? |
|? 2 | Peking??? | China? |
|? 3 | Chongqing | China? |
|? 4 | Tianjin?? | China? |
+----+-----------+--------+
cityjoin表:
+----+-----------+-------------+-----------+------------+
| id | Name????? | CountryCode | District? | Population |
+----+-----------+-------------+-----------+------------+
|? 1 | Shanghai? | CHN???????? | Shanghai? |??? 9696300 |
|? 2 | Peking??? | CHN???????? | Peking??? |??? 7472000 |
|? 3 | Chongqing | CHN???????? | Chongqing |??? 6351600 |
|? 4 | Tianjin?? | CHN???????? | Tianjin?? |??? 5286800 |
|? 5 | Wuhan???? | CHN???????? | Hubei???? |??? 4344600 |
+----+-----------+-------------+-----------+------------+
?
?countryjoin表:
?+------+-------------+---------------+-------------+------------+
| Code | Name??????? | Continent???? | SurfaceArea | Population |
+------+-------------+---------------+-------------+------------+
| ABW? | Aruba?????? | North America |????? 193.00 |???? 103000 |
| AFG? | Afghanistan | Asia????????? |?? 652090.00 |?? 22720000 |
| AGO? | Angola????? | Africa??????? |? 1246700.00 |?? 12878000 |
| AIA? | Anguilla??? | North America |?????? 96.00 |?????? 8000 |
| ALB? | Albania???? | Europe??????? |??? 28748.00 |??? 3401200 |
| CHN? | China?????? | Asia????????? |? 9600000.00 |? 130000000 |
+------+-------------+---------------+-------------+------------+
?
?1. Join
?select cityjoin.id, cityjoin.Name, countryjoin.Name c_Name from cityjoin left join countryjoin on cityjoin.Name=cityjoin.District and countryjoin.Code=cityjoin.CountryCode;
?我們要從 cityjoin 表要選出的記錄(不過(guò)只顯示id和Name)要滿足的條件是
?cityjoin.Name=cityjoin.District
?AND
?countryjoin.Code=cityjoin.CountryCode;
?怎么理解?就是說(shuō)我們把左右兩表作了連接,要顯示的就是city表中的直轄市,并且,這個(gè)直轄市所在的國(guó)家要在countryjoin表中對(duì)應(yīng)起來(lái),最后把完全滿足于這個(gè)條件的左右表需要的記錄返回過(guò)來(lái)。
?
?返回的記錄為:
?+----+-----------+--------+
| id | Name????? | c_Name |
+----+-----------+--------+
|? 1 | Shanghai? | China? |
|? 2 | Peking??? | China? |
|? 3 | Chongqing | China? |
|? 4 | Tianjin?? | China? |
+----+-----------+--------+
上述是最正確的情況,也滿足了需求。現(xiàn)在來(lái)破壞條件。
首先試著在cityjoin加上一條數(shù)據(jù),滿足cityjoin.Name=cityjoin.District,不過(guò)讓這個(gè)直轄市所在的國(guó)家在country表中找不到。
INSERT INTO cityjoin VALUES('SaltLake', 'USA', 'SaltLake', 500000);
此時(shí)的cityjoin表:
+----+-----------+-------------+-----------+------------+
| id | Name????? | CountryCode | District? | Population |
+----+-----------+-------------+-----------+------------+
|? 1 | Shanghai? | CHN???????? | Shanghai? |??? 9696300 |
|? 2 | Peking??? | CHN???????? | Peking??? |??? 7472000 |
|? 3 | Chongqing | CHN???????? | Chongqing |??? 6351600 |
|? 4 | Tianjin?? | CHN???????? | Tianjin?? |??? 5286800 |
|? 5 | Wuhan???? | CHN???????? | Hubei???? |??? 4344600 |
|? 6 | SaltLake? | USA???????? | SaltLake? |???? 500000 |
+----+-----------+-------------+-----------+------------+
然后重新執(zhí)行上面的select語(yǔ)句,結(jié)果仍舊一樣。
+----+-----------+--------+
| id | Name????? | c_Name |
+----+-----------+--------+
|? 1 | Shanghai? | China? |
|? 2 | Peking??? | China? |
|? 3 | Chongqing | China? |
|? 4 | Tianjin?? | China? |
+----+-----------+--------+
新加入的SaltLake,滿足了直轄市的條件,不過(guò)對(duì)應(yīng)的國(guó)家在country那邊是找不到的。所以不予顯示: 考慮我們要列擁有id,Name,c_Name3個(gè)列的表出來(lái),下面全是直轄市。不過(guò)如果我們將SaltLake的東西要顯示出來(lái),那么c_Name這里該顯示什么東西?沒(méi)錯(cuò),就是Null。顯然join不和Null打交道。換而言之,我們用join連接時(shí),左右表中任意可能出現(xiàn)Null的記錄,都不會(huì)被返回。那么如果我想顯示呢?如果想要顯示沒(méi)有對(duì)應(yīng)country的直轄市,left join就派上用場(chǎng)了。
2. Left/Right Join
依然是上面加入SaltLake的表,查詢語(yǔ)句中join換為left join.結(jié)果如下:
+----+-----------+--------+
| id | Name????? | c_Name |
+----+-----------+--------+
|? 1 | Shanghai? | China? |
|? 2 | Peking??? | China? |
|? 3 | Chongqing | China? |
|? 4 | Tianjin?? | China? |
|? 5 | Wuhan???? | NULL?? |
|? 6 | SaltLake? | NULL?? |
+----+-----------+--------+
恩?按照之前的設(shè)想應(yīng)該把直轄市SaltLake加入進(jìn)去,在c_Name顯示NULL才對(duì)。怎么Wuhan也加進(jìn)來(lái)了?
來(lái)看看LEFT JOIN的解釋:
LEFT JOIN 關(guān)鍵字會(huì)從左表 (table_name1) 那里返回所有的行,即使在右表 (table_name2) 中沒(méi)有匹配的行。
這下清楚了,之前的理解是有誤的。我們的join table on 后面的條件是一個(gè)整體,如果分開(kāi)來(lái)看,那就大錯(cuò)特錯(cuò)了。
再試試right join
+------+-----------+-------------+
| id?? | Name????? | c_Name????? |
+------+-----------+-------------+
|??? 1 | Shanghai? | China?????? |
|??? 2 | Peking??? | China?????? |
|??? 3 | Chongqing | China?????? |
|??? 4 | Tianjin?? | China?????? |
| NULL | NULL????? | Aruba?????? |
| NULL | NULL????? | Afghanistan |
| NULL | NULL????? | Angola????? |
| NULL | NULL????? | Anguilla??? |
| NULL | NULL????? | Albania???? |
+------+-----------+-------------+
我們可以總結(jié)出一句話: join是精確篩選,而left/right join則是在精確篩選的基礎(chǔ)之上,將左/右 表的記錄再單獨(dú)塞進(jìn)去,然后在 右/左表的列名下面留NULL。
我們可以用where字句把left join的結(jié)果集進(jìn)行逆向篩選:
?select cityjoin.id, cityjoin.Name, countryjoin.Name c_Name
?from cityjoin
?left join countryjoin
?on cityjoin.Name=cityjoin.District and countryjoin.Code=cityjoin.CountryCode
?where cityjoin.Name=cityjoin.District and countryjoin.Code=cityjoin.CountryCode;
?
結(jié)果如下:
+----+-----------+--------+
| id | Name????? | c_Name |
+----+-----------+--------+
|? 1 | Shanghai? | China? |
|? 2 | Peking??? | China? |
|? 3 | Chongqing | China? |
|? 4 | Tianjin?? | China? |
+----+-----------+--------+
總結(jié)
以上是生活随笔為你收集整理的自己对mysql中的Join的理解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 电子血压计
- 下一篇: 腾讯搜搜的分类搜索代码