想象一下:
你有两份名单:
- 一份是你们班所有同学的名单(花名册)。
- 另一份是参加了学校兴趣小组(比如足球队)的同学名单。
现在,你想整理一份全班同学的名单,并且在旁边标注出哪些人参加了足球队。
主表 (Main Table / Left Table)
- 就是你主要关心的那份名单,你希望这份名单上的每一个人都出现在最终结果里,一个都不能少。
- 在咱们这个例子里,“全班同学的花名册” 就是 主表。因为你的目标是列出 所有 同学的情况。
从表 (Secondary Table / Right Table)
- 这是提供补充信息的那份名单。它的信息是用来“附加”到主表上的。
- 在咱们这个例子里,“足球队队员名单” 就是 从表。它提供了“是否参加足球队”这个补充信息。
LEFT JOIN (左连接)
LEFT JOIN
做的事情就像这样:
- 拿出主表(全班花名册),把它放在左边。
- 拿出从表(足球队名单),把它放在右边。
- 开始配对:从主表(花名册)里挨个看每个同学。
- 查找匹配:看这个同学的名字是否也出现在从表(足球队名单)里。
- 如果找到了:很好!把这位同学的信息(比如姓名)和他参加足球队的信息(比如“是”)写在一起。
- 如果没找到:这位同学肯定在花名册上,但他不在足球队名单里。
LEFT JOIN
的关键就在这儿:即使没找到匹配,主表(花名册)里的这位同学也必须出现在最终结果里! 只不过,在他旁边的“是否参加足球队”那一栏,我们就只能填上 “否” 或者留空(在数据库里通常是NULL
,表示“没有信息”)。
核心思想: LEFT JOIN
就是 以左边的表(主表)为基准,把右边的表(从表)符合条件的信息“嫁接”过来。左边表的所有记录都会保留,右边表如果没有匹配的,就用空值(NULL)填充。 简单说就是:“左表说了算,右表来补充,补不上就空着”。
生动形象的例子:
例子一:学生和选课
-
主表 (Students):记录了学校所有学生的信息(学号, 姓名)。
学号 姓名 101 张三 102 李四 103 王五 -
从表 (CourseEnrollment):记录了选修了“美术课”的学生信息(学号, 课程)。
学号 课程 101 美术课 103 美术课 -
目标:我想看 所有学生 的名单,以及他们是否选了美术课。
-
使用
LEFT JOIN
:SELECT Students.姓名, CourseEnrollment.课程 FROM Students LEFT JOIN CourseEnrollment ON Students.学号 = CourseEnrollment.学号;
-
结果:
姓名 课程 张三 美术课 李四 NULL 王五 美术课 你看,所有学生(张三、李四、王五)都在结果里,一个没少。李四没选美术课,他对应的课程信息就是空的(NULL)。这就是
LEFT JOIN
的效果:保证主表(学生表)的完整性。
例子二:商品和折扣
-
主表 (Products):记录了商店里所有的商品(商品ID, 名称, 原价)。
商品ID 名称 原价 P001 牛奶 5 P002 面包 3 P003 鸡蛋 10 -
从表 (Discounts):记录了当前正在打折的商品信息(商品ID, 折扣价)。
商品ID 折扣价 P001 4 P003 8 -
目标:我想看 所有商品 的列表,以及它们的折扣价(如果有的话)。
-
使用
LEFT JOIN
:SELECT Products.名称, Products.原价, Discounts.折扣价 FROM Products LEFT JOIN Discounts ON Products.商品ID = Discounts.商品ID;
-
结果:
名称 原价 折扣价 牛奶 5 4 面包 3 NULL 鸡蛋 10 8 同样,所有商品(牛奶、面包、鸡蛋)都列出来了。面包没打折,它的折扣价就是空的(NULL)。
LEFT JOIN
确保了我们能看到所有商品的情况,无论它是否参与打折。
总结一下:
- 主表:你最关心的那个表,它的所有记录都要出现在结果里。
- 从表:提供补充信息的表。
- LEFT JOIN:以主表为基础,把从表中能匹配上的信息加进来;如果从表中没有匹配的,主表的记录仍然保留,对应的从表信息位置填 NULL。