“一张表是孤独,两张表才是爱情。”
你有没有发现:
单表查询就像一个人吃饭,有点寂寞;
而多表查询,就是一场数据库世界的相亲大会!
2.1 INNER JOIN:命中注定的一对
只保留两个表中都能匹配上的记录。
就像相亲成功,牵手走在一起。
SELECT *
FROM boy b
INNER JOIN girl g ON b.girl_id = g.id;
✅ 特点:只返回有对象的数据,单身狗被过滤了。
2.2 LEFT JOIN:深情男的等待
左边的表全部保留,右边没匹配就为 NULL。
就像一个男生一直在等,女生不来也爱你。
SELECT *
FROM boy b
LEFT JOIN girl g ON b.girl_id = g.id;
特点:左边全在,右边可能空。适合查“有没有对象”的人。
2.3 RIGHT JOIN:痴情女的守候
和 LEFT JOIN 相反,右边的表全保留。
女生不管男生在不在,都来了。
SELECT *
FROM boy b
RIGHT JOIN girl g ON b.girl_id = g.id;
特点:女生都在,男生可能空。适合查“有没有男朋友”。
2.4 FULL JOIN:宇宙级的包容(MySQL 不原生支持)
所有数据都保留,没有匹配的就 NULL。
爱无界限,不分男女。
-- MySQL 没有 FULL JOIN,但可以用 UNION 实现
SELECT * FROM table1 LEFT JOIN table2 ...
UNION
SELECT * FROM table1 RIGHT JOIN table2 ...
特点:全员出席,谁也不落下。
3.1 WHERE 子查询:先找对象再约会
SELECT name
FROM boy
WHERE girl_id = (
SELECT id
FROM girl
WHERE name = '小红'
);
解释:先找到“小红”的 ID,再去男孩表里找她的男朋友。
3.2 FROM 子查询:临时组队闯关
SELECT *
FROM (
SELECT name, age
FROM user
WHERE age > 20
) AS temp_user
WHERE temp_user.name LIKE '张%';
解释:先创建一个临时队伍(temp_user),然后再筛选出姓张的。
3.3 EXISTS 子查询:存在感测试
SELECT name
FROM boy b
WHERE EXISTS (
SELECT 1
FROM girl g
WHERE g.id = b.girl_id
);
解释:只有存在女朋友的男生才被选出来,单身狗请退场。
4.1 UNION:去重的浪漫合并
SELECT name FROM boy
UNION
SELECT name FROM girl;
特点:自动去重,就像两个人的爱情,不接受第三者。
4.2 UNION ALL:不挑食的合并狂魔
SELECT name FROM boy
UNION ALL
SELECT name FROM girl;
特点:来者不拒,重复也行,效率更高!
SELECT e1.name AS employee, e2.name AS manager
FROM employee e1
LEFT JOIN employee e2 ON e1.manager_id = e2.id;
解释:员工和经理是同一张表里的不同角色,这就是“自己带自己飞”!
SELECT *
FROM boy, girl;
⚠️ 后果:所有男生和所有女生随机配对,结果爆炸!
5 个男生 × 5 个女生 = 25 对情侣?
如果是 1000×1000?别试了,数据库会哭的。
场景:学校管理系统
表结构:
student(id, name, class_id)
class(id, name, teacher_id)
teacher(id, name)
题目 1:列出每个学生的名字和他的班级名和老师名
SELECT s.name AS student_name, c.name AS class_name, t.name AS teacher_name
FROM student s
JOIN class c ON s.class_id = c.id
JOIN teacher t ON c.teacher_id = t.id;
题目 2:找出没有分配班级的学生
SELECT s.name
FROM student s
LEFT JOIN class c ON s.class_id = c.id
WHERE c.id IS NULL;