SQL 表连接(JOIN)详解

    在实际开发中,数据库往往是多表结构,我们经常需要从多个表中组合数据。这个过程就离不开 SQL 连接(JOIN) 的使用。

    SQL 提供了多种连接方式,用于根据某些字段的关联关系,将两个或多个表的数据拼接在一起。

    🔗 1. INNER JOIN(内连接)

    这是最常用的连接方式。只有当两个表中都有匹配记录时,对应的行才会出现在结果中。

    🧠 场景理解:

    假设你有一个用户表 users 和一个订单表 orders,你想查询哪些用户下过订单。

    ✅ 示例 SQL:

    SELECT users.name, orders.product

    FROM users

    INNER JOIN orders ON users.id = orders.user_id;

    结果:只显示有订单的用户。

    🔗 2. LEFT JOIN(左连接)

    左连接会返回左边表的所有行,即使右表中没有匹配的记录。右表中匹配不到的部分会用 NULL 填充。

    🧠 场景理解:

    你想查询所有用户的订单情况,哪怕某些用户没下过订单,也希望他们出现在结果里。

    ✅ 示例 SQL:

    SELECT users.name, orders.product

    FROM users

    LEFT JOIN orders ON users.id = orders.user_id;

    结果:所有用户都会显示,没下过单的用户订单字段为 NULL。

    🔗 3. RIGHT JOIN(右连接)

    右连接和左连接正好相反,它会返回右边表的所有行,即使左表中没有匹配。

    🧠 场景理解:

    你想查看订单记录,即使有些订单的用户信息丢失了,也想保留订单行。

    ✅ 示例 SQL:

    SELECT users.name, orders.product

    FROM users

    RIGHT JOIN orders ON users.id = orders.user_id;

    结果:所有订单都会显示,即使有些订单的用户不存在或被删除。

    🔗 4. FULL JOIN(全连接)

    全连接会返回左表和右表的所有行。任何一边没有匹配的地方都用 NULL 填充。

    ⚠️ 注意:MySQL 默认不支持 FULL JOIN,可以使用 UNION 实现。

    ✅ 示例 SQL:

    SELECT A.*, B.*

    FROM A

    FULL JOIN B ON A.id = B.a_id;

    🔗 5. CROSS JOIN(交叉连接)

    交叉连接(又称笛卡尔积)会将左表的每一行与右表的每一行做组合。一般用于生成所有可能的配对组合。

    ✅ 示例 SQL:

    SELECT colors.color, sizes.size

    FROM colors

    CROSS JOIN sizes;

    如果 colors 有 3 行,sizes 有 4 行,则结果有 3×4 = 12 行。

    🧰 小技巧与建议

    想拼接多个查询条件时,用 WHERE 1=1 可以方便地追加:

    WHERE 1=1 AND status='done' AND user_id=123

    在 SELECT 中使用 CASE WHEN ... THEN ... END 可以对数据进行分类或默认值设置:

    SELECT name,

    CASE WHEN age IS NULL THEN 0 ELSE age END AS display_age

    FROM users;

    如果只需要查看是否有关联记录,可以用 EXISTS 或 LEFT JOIN + IS NULL 的方式实现。

    🧭 连接方式选择建议

    目标

    推荐连接

    只需要匹配成功的记录

    INNER JOIN

    需要保留主表所有记录

    LEFT JOIN

    保留右表所有记录(少见)

    RIGHT JOIN

    获取全部记录并对比缺失部分

    FULL JOIN

    获取所有可能的组合

    CROSS JOIN

    🎯 总结一句话

    INNER JOIN 查交集,LEFT JOIN 保左边,RIGHT JOIN 保右边,FULL JOIN 是并集,CROSS JOIN 生成所有组合。