一篇搞定MySQL多表查询

 “一张表是孤独,两张表才是爱情。”

一、前言:从单表到多表的奇妙旅程


你有没有发现:

单表查询就像一个人吃饭,有点寂寞;
而多表查询,就是一场数据库世界的相亲大会!


二、JOIN 的前世今生:表与表之间的缘分
 

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
);

解释:只有存在女朋友的男生才被选出来,单身狗请退场。

四、UNION & UNION ALL:合并数据的两种态度


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;

你可能感兴趣的:(mysql)