在处理数据库时,我们常常需要从多个表中提取数据。比如想知道一个城市的天气情况,同时又想知道这个城市的具体位置。这就需要将 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 类型(如内连接、左外连接、右外连接和全外连接),我们可以灵活地处理各种数据组合需求。同时,自连接也为我们提供了处理复杂逻辑的手段。