SQL中的Join你用对了么?

你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。

点击下方👇关注公众号,带你一起复习后端技术,看看面试考点,补充积累技术知识,每天都为面试准备积累


在 MySQL 中,JOIN、LEFT JOIN、RIGHT JOIN 等是常用的用于连接多个表的操作符。它们各自有不同的用途和特点,在面试中,了解这些操作符的区别和应用非常重要。下面是对这些 JOIN 操作符的详细解释,以及一些常见的面试问题和应用场景。


01
JOIN (INNER JOIN)


定义:JOIN 默认是 INNER JOIN,表示“内连接”,只返回两个表中匹配的记录。如果表 A 和表 B 通过某个条件连接,INNER JOIN 只会返回那些在 A 和 B 中都有的匹配项。

常见用途:

  • 当你需要从两个表中获取相匹配的数据时使用。

  • 如果你只关心两个表之间有关系的记录,不关心无匹配记录,可以使用 INNER JOIN。

SELECT A.id, A.name, B.departmentFROM employees AINNER JOIN departments B ON A.department_id = B.id;

这将返回所有在 employees 表和 departments 表中都有匹配项的记录。


    02
    LEFT JOIN (LEFT OUTER JOIN)


    定义:LEFT JOIN 返回左表(LEFT)的所有记录,即使右表(RIGHT)没有匹配的记录。在没有匹配记录的情况下,右表的字段将返回 NULL。

    常见用途:当你需要返回左表中的所有记录,并希望获取右表中与之相关的数据。如果右表没有匹配数据,仍然希望返回左表的数据。

    SELECT A.id, A.name, B.departmentFROM employees ALEFT JOIN departments B ON A.department_id = B.id;

    这将返回所有员工(即使他们没有部门),如果某个员工没有部门,则 department 列会返回 NULL。


    应用场景:

    • 获取所有用户及其订单,如果某些用户没有订单,也要显示出来。

    • 查询所有产品及其销量,如果某些产品没有销量记录,也要显示出来。


    03
    RIGHT JOIN (RIGHT OUTER JOIN)


    定义:RIGHT JOIN 返回右表(RIGHT)的所有记录,即使左表(LEFT)没有匹配的记录。在没有匹配记录的情况下,左表的字段将返回 NULL。

    常见用途:
    • 类似于 LEFT JOIN,但是返回的是右表的数据。

    • 很少用,因为通常可以通过交换 LEFT JOIN 的顺序来得到相同的结果。


    SELECT A.id, A.name, B.departmentFROM employees ARIGHT JOIN departments B ON A.department_id = B.id;

    这将返回所有部门的信息,即使某些部门没有员工。没有员工的部门将返回 NULL 在员工相关的字段。


    应用场景:当你关心右表(比如部门)的所有数据,并希望获取与左表(比如员工)相关的数据时。


    04
    FULL JOIN (FULL OUTER JOIN)


    定义:FULL JOIN 或 FULL OUTER JOIN 会返回左表和右表中所有的记录,任何一边没有匹配的记录都用 NULL 填充。

    注意:MySQL 不直接支持 FULL JOIN。你可以通过将 LEFT JOIN 和 RIGHT JOIN 结合起来模拟 FULL JOIN。

    当你需要返回两个表中所有的记录,不管是否有匹配项。

    SELECT A.id, A.name, B.departmentFROM employees ALEFT JOIN departments B ON A.department_id = B.idUNIONSELECT A.id, A.name, B.departmentFROM employees ARIGHT JOIN departments B ON A.department_id = B.id;

    模拟 FULL JOIN:这将返回所有的员工和部门,包括没有匹配记录的员工和部门。


    05
    CROSS JOIN


    定义:CROSS JOIN 返回两个表的笛卡尔积,即左表的每一行与右表的每一行都匹配。CROSS JOIN 不需要 ON 条件。

    常见用途:用于生成两个表的笛卡尔积,通常用于生成组合或者测试数据。

    SELECT A.idB.nameFROM employees ACROSS JOIN departments B;

    如果 employees 表有 10 行数据,departments 表有 5 行数据,CROSS JOIN 将返回 50 行数据(10 * 5)。


    06
    SELF JOIN


    定义:SELF JOIN 是对同一张表进行连接。它通常是通过给表取别名来实现的,通常用于查找表中相互关联的记录。

    常见用途:用于查找表中有某种关系的记录,如查找某个员工的经理(如果表中有经理 ID)。

    SELECT A.name AS Employee, B.name AS ManagerFROM employees ALEFT JOIN employees B ON A.manager_id = B.id;

    这将返回所有员工及其经理(如果有的话)。




    07
    面试题


    7.1 在查询中,JOIN 和子查询哪个更高效?

    JOIN 通常比子查询效率更高,尤其是当连接的表有索引时,JOIN 可以利用索引优化查询。

    子查询会先执行查询,然后再将结果传递给外部查询,这样可能会导致多次计算,因此通常效率较低。

    但是,具体情况还需要根据查询的复杂性、数据量以及索引情况来判断。


    7.2 你如何优化使用 JOIN 的查询?

    使用索引:确保连接条件(如外键、ID 等)上有索引,可以加速连接操作。

    避免不必要的连接:仅连接需要的数据表,避免连接过多的表。

    限制结果集大小:使用 WHERE 子句来减少返回的数据量,避免查询过多不必要的行。

    使用 EXPLAIN:使用 EXPLAIN 语句查看查询执行计划,分析查询效率并找出可能的瓶颈。


    7.3 MySQL 中的 JOIN 是否会导致 Cartesian Product(笛卡尔积)?

    是的,JOIN 操作可能会导致笛卡尔积,尤其是当连接条件不正确或没有有效的连接条件时。

    笛卡尔积会生成两个表的所有可能组合,通常会产生大量不必要的数据。

    为了避免笛卡尔积,必须确保在 JOIN 语句中使用合适的连接条件。


    7.4 什么是 "ON" 和 "WHERE" 的区别,能在 JOIN 中同时使用吗?

    ON:用于指定 JOIN 条件,即如何匹配两个表中的记录。

    WHERE:用于筛选查询结果,通常用于过滤连接后的结果集。

    在 JOIN 中可以同时使用 ON 和 WHERE,但它们的作用不同。ON 用于定义连接条件,WHERE 用于进一步过滤结果集。


    今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!

    END


    扫码关注

    一起积累后端知识
    不积跬步,无以至千里
    不积小流,无以成江海

    喜欢此内容的人还喜欢

    谈谈id那些事(五)——美团的 Leaf 的ID生成


    一个阿里二面面试官必问的问题


    谈谈id那些事(三)——阿里巴巴的 TDDL的ID生成


    分享面试:mysql数据库索引失效的情况


    面试常被忽略的问题——内存区域划分