🗄️ 第三章 操作数据库-SQL的使用方法
📄 一句话概括

JOIN 把拆开的多张表按公共字段临时拼回一张宽表——2-3 的【拆表】在这里完成闭环,拆得出去也拼得回来。

📝 本节和前面几节的关系

第二章讲透了【为什么拆表】;本章查询技能攒齐了单表十八般武艺;从本节起三节学【拼表】:先讲总纲(本节),再分【内连接】(3-21)和【外连接】(3-22)两大门派。

一、为什么要 JOIN

2-3 拆表后:学生表只有【class 的编号】,班级的老师、名字都在别的表里。想知道【张三的班主任是谁】,一张表答不了——JOIN 按【对号】把几张表临时拼成一张宽表。

先备好第二张表:

-- 班级表:1 班刘老师、2 班陈老师(3 班的老师暂缺——伏笔)
CREATE TABLE classes (
  id      INTEGER PRIMARY KEY,
  teacher TEXT
);
INSERT INTO classes VALUES (1, '刘老师');
INSERT INTO classes VALUES (2, '陈老师');

二、JOIN 的语法骨架

SELECT 列...
FROM 表A
JOIN 表B ON 表A.公共列 = 表B.公共列;

三个零件:

三、一句真 JOIN

-- 张三李四王五赵六 + 各自班主任
SELECT students.name, students.class, classes.teacher
FROM students
JOIN classes ON students.class = classes.id;

输出:

name  class  teacher
张三  1      刘老师
李四  1      刘老师
王五  2      陈老师
赵六  2      陈老师

——钱七不在! 他的 class 是 3,classes 表里没有 3 号班——对不上号的行被丢掉了。这就是【内连接】(3-21)的脾气:只留两边都对上的。

四、动手 Demo:拼一张三表宽表

把 3-6 的 students 准备块也跑上,然后:

SELECT students.id, students.name, classes.teacher
FROM students
JOIN classes ON students.class = classes.id;

再试查【每个老师的班级人数】——JOIN+GROUP BY 连打:

SELECT classes.teacher, COUNT(*) AS 带生数
FROM students
JOIN classes ON students.class = classes.id
GROUP BY classes.teacher;

输出:刘老师 2、陈老师 2(钱七对不上号,不进统计)。

看到什么算成功:宽表四行(钱七出局)、分组统计两行——JOIN 管拼、GROUP BY 管堆,零件可以自由组合。

五、30 秒实验

故意把 ON 条件写错对不上的列:JOIN classes ON students.class = students.id;——能跑但结果是【乱点鸳鸯谱】的宽表(行数看着对、内容全错)。JOIN 不报错只出错数据,比报错更险——跑 JOIN 前先想清【谁的外键对谁的主键】。

六、常见误区

  1. "JOIN 会把数据物理合进一张表存起来" —— 临时拼装,库里三张表还是三张表(2-3 误区第三条的延续)。
  2. "ON 条件随便写个等式就行" —— ON 是拼表的灵魂:外键对主键写错,宽表整张错;拼表不报错、只出错数据。
  3. "JOIN 一定保留左表全部行" —— 本节的 JOIN(= INNER JOIN)只留对上号的;钱七就被丢了。想留全左表,用外连接(3-22)。
自测三问(点开对答案) 1. JOIN 的三个零件是什么? **谁跟谁拼(A JOIN B)+对号规矩(ON)+点名归属(表名.列名)**。 2. ON 通常是谁对谁? **一方的对外键 = 另一方的主键**。 3. 钱七为什么没出现在结果里? **class=3 在 classes 表对不上号——本节的 JOIN 只留两边都匹配的行**。

相关笔记