在處理數據庫時,我們常常需要從多個表中提取數據。比如想知道一個城市的天氣情況,同時又想知道這個城市的具體位置。這就需要將?weather
?表和?cities
?表結合起來查詢。這種操作在 SQL 中被稱為?JOIN 查詢。
現在看下兩種表的情況
1.weather 表:
2.cities?表:
一.JOIN 查詢的基礎
現在有兩個表:weather
?和?cities
。weather?表記錄了不同城市的天氣情況,而?cities
?表記錄了城市的名稱和位置。
想找出所有城市的天氣記錄以及它們的位置,我們可以使用?JOIN 語句來連接兩個表。語句如下:
select?*?
from?weather?join?cities?on?city = name;
也可以使用別名,在兩個表有相同字段名稱時來區別它們。
???????
SELECT?*?
FROM?weather?as?w?JOIN?cities?as?c?ON?w.city?=?c.name;
上面語句的意思是:從 weather 表中取出每一行,然后在 cities 表中查找 name 列與 weather 表中的 city 列相匹配的行。如果找到匹配的行,就將這兩行的內容組合在一起返回。
也可以按照要求查詢特點字段。
???????
SELECT w.id,w.city,w.prcp,c.location?
FROM weather?as?w JOIN cities?as?c ON w.city = c.name;
注意
? ? 列名沖突:如果兩個表中有同名列,需要使用表名來限定列名,例如 w.city 或 c.name。
? ? 明確指定輸出列:為了避免不必要的列重復,建議明確指定需要輸出的列,而不是使用 SELECT *。
二.外連接(Outer Join)
在上面的例子中,西安?沒有出現在結果中,因為 cities 表中沒有?西安?的記錄。如果希望即使沒有匹配的行也能顯示 weather 表中的記錄,可以使用?外連接。
1.左外連接(LEFT OUTER JOIN)
左外連接會返回左表(weather
)的所有行,即使右表(cities
)中沒有匹配的行。如果沒有匹配的行,右表的列將顯示為?NULL
。
???????
select?w.id,w.city,w.prcp , c.id,c.name,c.location?
from?weather w
left?outer?join?cities c?-- 這里的 outer可以省略不寫
on?w.city?=?c.name;
2.右外連接(RIGHT OUTER JOIN)
右外連接會返回右表(cities
)的所有行,即使左表(weather
)中沒有匹配的行。
???????
select?w.id,w.city,w.prcp , c.id,c.name,c.location?
from?weather w
right?join?cities c
on?w.city = c.name;
3.全外連接(FULL OUTER JOIN)
全外連接會返回左表和右表的所有行,無論是否有匹配的行。如果某一行在另一表中沒有匹配的行,那么對應的列將顯示為?NULL
。
???????
select?w.id,w.city,w.prcp , c.id,c.name,c.location?
from?weather w
full?outer?join?cities c ?-- 這里的 outer可以省略不寫
on?w.city?=?c.name;
外連接可以簡單理解為?指向誰,以誰為主。
三.自連接(Self Join)
有時候,我們可能需要將一個表與自己連接起來。例如想找出杭州的溫度范圍在其他天氣記錄之內的天氣記錄數據。
語句如下:
???????
SELECT?distinct? w1.city,?
? ? ? w1.temp_low?AS?low,?
? ? ? w1.temp_high?AS?high,
? ? ? w2.city,?
? ? ? w2.temp_low?AS?low,?
? ? ? w2.temp_high?AS?high
FROM?weather w1
JOIN?weather w2
ON?w1.temp_low?<?w2.temp_low?AND?w1.temp_high?>?w2.temp_high
where?w1.city?=?'杭州';
在這個查詢中,我們將 weather 表重新標記為 w1 和 w2,以便區分連接的左部和右部。
總結下:JOIN 查詢是 SQL 中非常強大的工具,可以幫助我們從多個表中提取和組合數據。
通過使用不同的 JOIN 類型(如內連接、左外連接、右外連接和全外連接),我們可以靈活地處理各種數據組合需求。同時,自連接也為我們提供了處理復雜邏輯的手段。