SQL之各种join小结详细讲解

SQL Left Join, Right Join, Inner Join, and Natural Join 各种Join小结

在SQL语言中,存在着各种Join,有Left Join, Right Join, Inner Join, and Natural Join等,对于初学者来说肯定一头雾水,都是神马跟神马啊,它们之间到底有着怎样的区别和联系呢,我们先用一张图片来说明:

上面这张图很好的阐释了Left Join, Right Join, Inner Join,和Full Outer Join的区别,下面用我们用一个简单的例子来帮助我们理解和区分,现在有两个表Person和Address:

-- Table Person
+----------+-----------+----------+
| PersonId | FirstName | LastName |
+----------+-----------+----------+
|        1 | Zhang     | San      |
|        2 | Li        | Si       |
|        3 | Wang      | Wu       |
|        4 | Yang      | Liu      |
+----------+-----------+----------+

-- Table Address
+-----------+----------+---------------+-------+
| AddressId | PersonId | City          | State |
+-----------+----------+---------------+-------+
|         1 |        2 | San Francisco | CA    |
|         2 |        3 | Los Angeles   | CA    |
|         3 |        1 | San Diego     | CA    |
+-----------+----------+---------------+-------+

我们下面一个一个的来看:

Left Join: returns all rows from the left table (table1), with the matching rows in the right table (table2). The result is NULL in the right side when there is no match.

左交:返回左表的所有行和匹配的右表的行,如果没有匹配上的用NULL.

SELECT * FROM Person LEFT JOIN Address ON Person.PersonId = Address.PersonId; 
+----------+-----------+----------+-----------+----------+---------------+-------+
| PersonId | FirstName | LastName | AddressId | PersonId | City   | State |
+----------+-----------+----------+-----------+----------+---------------+-------+
|        2 | Li        | Si       |         1 |        2 | San Francisco | CA    |
|        3 | Wang      | Wu       |         2 |        3 | Los Angeles   | CA    |
|        1 | Zhang     | San      |         3 |        1 | San Diego     | CA    |
|        4 | Yang      | Liu      |      NULL |     NULL | NULL          | NULL  |
+----------+-----------+----------+-----------+----------+---------------+-------+

Right Join: returns all rows from the right table (table2), with the matching rows in the left table (table1). The result is NULL in the left side when there is no match.

右交:返回右表的所有行和匹配的左表的行,如果没有匹配上的用NULL.

SELECT * FROM Person RIGHT JOIN Address ON Person.PersonId = Address.PersonId; 
+----------+-----------+----------+-----------+----------+---------------+-------+
| PersonId | FirstName | LastName | AddressId | PersonId | City          | State |
+----------+-----------+----------+-----------+----------+---------------+-------+
|        1 | Zhang     | San      |         3 |        1 | San Diego     | CA    |
|        2 | Li        | Si       |         1 |        2 | San Francisco | CA    |
|        3 | Wang      | Wu       |         2 |        3 | Los Angeles   | CA    |
|     NULL | NULL      | NULL     |         4 |        5 | Memphis       | TN    |
+----------+-----------+----------+-----------+----------+---------------+-------+

Inner Join: selects all rows from both tables as long as there is a match between the columns in both tables.

内交: 选择左右表中关键字匹配上的行。

SELECT * FROM Person INNER JOIN Address ON Person.PersonId = Address.PersonId;  +----------+-----------+----------+-----------+----------+---------------+-------+
| PersonId | FirstName | LastName | AddressId | PersonId | City          | State |
+----------+-----------+----------+-----------+----------+---------------+-------+
|        1 | Zhang     | San      |         3 |        1 | San Diego     | CA    |
|        2 | Li        | Si       |         1 |        2 | San Francisco | CA    |
|        3 | Wang      | Wu       |         2 |        3 | Los Angeles   | CA    |
+----------+-----------+----------+-----------+----------+---------------+-------+

Full Join: returns all rows from the left table (table1) and from the right table (table2), and it combines the result of both LEFT and RIGHT joins.

全交: 返回左表的所有行和右表的所有行,是左交和右交的联合。

注意,由于MySql中没有Full Join命令,所以我们通过把Left Join和Right Join的结果Union起来也是可以的:

SELECT * FROM Person LEFT JOIN Address ON Person.PersonId = Address.PersonId UNION
SELECT * FROM Person RIGHT JOIN Address ON Person.PersonId = Address.PersonId;  +----------+-----------+----------+-----------+----------+---------------+-------+
| PersonId | FirstName | LastName | AddressId | PersonId | City          | State |
+----------+-----------+----------+-----------+----------+---------------+-------+
|        2 | Li        | Si       |         1 |        2 | San Francisco | CA    |
|        3 | Wang      | Wu       |         2 |        3 | Los Angeles   | CA    |
|        1 | Zhang     | San      |         3 |        1 | San Diego     | CA    |
|        4 | Yang      | Liu      |      NULL |     NULL | NULL          | NULL  |
|     NULL | NULL      | NULL     |         4 |        5 | Memphis       | TN    |
+----------+-----------+----------+-----------+----------+---------------+-------+

Natural Join: creates an implicit join clause for you based on the common columns in the two tables being joined. Common columns are columns that have the same name in both tables. A NATURAL JOIN can be an INNER join, a LEFT OUTER join, or a RIGHT OUTER join. The default is INNER join.

自然交: 根据左右两表的相同列创建一个隐含的join操作,相同列就是两表中列名相同的两列。自然交可以是内交,左交或者是右交。默认是内交。

SELECT * FROM Person NATURAL JOIN Address; 

+----------+-----------+----------+-----------+---------------+-------+
| PersonId | FirstName | LastName | AddressId | City          | State |
+----------+-----------+----------+-----------+---------------+-------+
|        1 | Zhang    | San      |         3 | San Diego     | CA    |
|        2 | Li        | Si       |         1 | San Francisco | CA    |
|        3 | Wang      | Wu       |         2 | Los Angeles   | CA    |
+----------+-----------+----------+-----------+---------------+-------+

最后注意一下,下面等号左右两边的关键字是等价的:

A LEFT JOIN B      =       A LEFT OUTER JOIN B
A RIGHT JOIN B     =       A RIGHT OUTER JOIN B
A FULL JOIN B      =       A FULL OUTER JOIN B
A INNER JOIN B     =       A JOIN B

到此这篇关于SQL之各种join小结详细讲解的文章就介绍到这了,更多相关SQL之各种join小结内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅谈mysql join底层原理

    目录 join算法 驱动表和非驱动表的区别 1.Simple Nested-Loop Join,简单嵌套-无索引的情况 2.Index Nested-Loop Join-有索引的情况 3.Block Nested-Loop Join ,join buffer缓冲区 缓冲区大小 数据量大的表和数据量小的表如何选择连接顺序 细节 join算法 mysql只支持一种join算法:Nested-Loop Join(嵌套循环连接),但Nested-Loop Join有三种变种: Simple Nested

  • MYSQL数据库基础之Join操作原理

    Join使用的是Nested-Loop Join算法,Nested-Loop Join有三种 select * from t1 join t2 on t1.a = t2.a; -- a 100条数据, b 1000条数据 Simple Nested-Loop Join 会遍历t1全表,t1作为驱动表,t1中的每一条数据都会到t2中做一次全表查询,该过程会比较100*1000次. 每次在t2中做全表查询时,全表扫描可就不保证在内存里了,Buffer Pool会淘汰,有可能在磁盘. Block Ne

  • 为什么代码规范要求SQL语句不要过多的join

    送分题 面试官:有操作过Linux吗? 我:有的呀 面试官:我想查看内存的使用情况该用什么命令 我:free 或者 top 面试官:那你说一下用free命令都可以看到啥信息 我:那,如下图所示 可以看到内存以及缓存的使用情况 total 总内存 used 已用内存 free 空闲内存 buff/cache 已使用的缓存 avaiable 可用内存 面试官:那你知道怎么清理已使用的缓存吗(buff/cache) 我:em- 不知道 面试官:sync; echo 3 > /proc/sys/vm/d

  • 解决Mysql的left join无效及使用的注意事项说明

    Mysql的left join无效及使用 今天写sql发现使用left join 没有把左边表的数据全部查询出来,让我郁闷了一会,后来仔细研究了一会才知道自己犯了个常识性的错误(我是菜鸟) 这是原sql 这样的查询并不能将tb_line这张表的数据都查询出来,好尴尬... 后面我才知道原来当我们进行多表查询,在执行到where之前,会先形成一个临时表 而on就是临时表中的条件筛选,使用left join则不管条件是否为真,都会查询出左边表的数据,条件为假的,则显示为null where则是在临时

  • mysql高效查询left join和group by(加索引)

    mysql高效查询 mysql牺牲了group by来增加left join的速度(前提是加了索引). user表:10万数据 实例1: 200秒左右 SELECT U.id, A.favorite_count FROM (SELECT id from user) U LEFT JOIN ( -- 点赞数 SELECT favorite_by AS user_id, SUM(favorite_count) AS favorite_count FROM favorite GROUP BY favo

  • MySQL的join buffer原理

    一.MySQL的join buffer 在MySQL对于join操作的处理过程中,join buffer是一个重要的概念,也是MySQL对于table join的一个重要的优化手段.虽然这个概念实现并不复杂,但是这个是实现MySQL join连接优化的一个重要方法,在"暴力"连接的时候可以极大提高join查询的效率. 关于这个概念的权威说明当然是来自MySQL文档中对于这个概念的说明,说明的文字不多,但是言简意赅,说明了这个优化的主要实现思想: Assume you have the

  • mysql left join快速转inner join的过程

    在日常优化过程中,发现一个怪事情,同一个SQL出现两个完全不一样执行计划,left join 连驱动表都可以变成不一样. 对于left join,如果where条件里有被关联表过滤,left join有可能被转成inner join ,本案例中shopInfo有ShopCategory = 'LOC'过滤条件: 保证shopInfo的记录非NULL,因此left join在优化过程中可以转为inner join. 那么O和S的JOIN顺序就是可以交换的. 验证结论: 创建表: --班级表 CRE

  • SQL语句中JOIN的用法场景分析

    记录:256 写SQL最高境界:SELECT * FROM 表名.当然这是一句自嘲.探究一下SQL语句中JOIN的用法,直到经历这个场景,变得想验证一下究竟. 一.场景 把关系型数据库A中表TEST_TB01和TEST_TB02迁移到大数据平台M(MaxCompute大数据平台).TEST_TB01单表1000万条记录,TEST_TB02单表80万条记录. 在关系型数据库中,TEST_TB01和TEST_TB02中有主键约束.在产生新增业务数据时,不会存在重复数据插入.但是,当数据迁移到大数据平

  • SQL之各种join小结详细讲解

    SQL Left Join, Right Join, Inner Join, and Natural Join 各种Join小结 在SQL语言中,存在着各种Join,有Left Join, Right Join, Inner Join, and Natural Join等,对于初学者来说肯定一头雾水,都是神马跟神马啊,它们之间到底有着怎样的区别和联系呢,我们先用一张图片来说明: 上面这张图很好的阐释了Left Join, Right Join, Inner Join,和Full Outer Jo

  • MyBatis 超详细讲解动态SQL的实现

    目录 情景: 概述: SQL元素: <if>: <choose>: <where>: <trim>: <set>: <foreach>: <bind>: 情景: 我们在使用JDBC或者其他类似的框架开发进行数据库开发时,通常要根据需求动手组装SQL,不用想都觉得是件很痛苦的事情了,而Mybatis框架提供的对SQL语句动态组装的功能,能很好地解决这个麻烦. 概述: 动态SQL是MyBatis框架的一个强大特性,MyBati

  • MyBatis 详细讲解动态 SQL的使用

    目录 MyBatis 框架动态 SQL 环境准备 动态 SQL 之 if 动态 SQL 之 where 动态 SQL 之 foreach 动态 SQL 之代码片段 MyBatis 框架动态 SQL 动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句.这里的条件判断使用的表达式为 OGNL 表达式.常用的动态 SQL 标签有<if>.<where>.<choose/>.<foreach>等. MyBatis 的动态 S

  • MyBatis 超详细讲解动态SQL的实现

    目录 情景: 概述: SQL元素: <if>: <choose>: <where>: <trim>: <set>: <foreach>: <bind>: 情景: 我们在使用JDBC或者其他类似的框架开发进行数据库开发时,通常要根据需求动手组装SQL,不用想都觉得是件很痛苦的事情了,而Mybatis框架提供的对SQL语句动态组装的功能,能很好地解决这个麻烦. 概述: 动态SQL是MyBatis框架的一个强大特性,MyBati

  • MyBatis 详细讲解动态 SQL的使用

    目录 MyBatis 框架动态 SQL 环境准备 动态 SQL 之 if 动态 SQL 之 where 动态 SQL 之 foreach 动态 SQL 之代码片段 MyBatis 框架动态 SQL 动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句.这里的条件判断使用的表达式为 OGNL 表达式.常用的动态 SQL 标签有<if>.<where>.<choose/>.<foreach>等. MyBatis 的动态 S

  • Mybatis超详细讲解构建SQL方法

    目录 1 SQL 构建对象介绍 1.1.1 介绍 1.1.2 实现准备 2 查询功能的实现 3 新增功能的实现 4 修改功能的实现 5 删除功能的实现 1 SQL 构建对象介绍 1.1.1 介绍 我们之前通过注解开发时,相关 SQL 语句都是自己直接拼写的.一些关键字写起来比较麻烦.而且容易出错. MyBatis 给我们提供了 org.apache.ibatis.jdbc.SQL 功能类,专门用于构建 SQL 语句 1.1.2 实现准备 编写指定调用方法 package com.yyl.sql;

  • MySql中sql语句执行过程详细讲解

    目录 前言: sql语句的执行过程: 查询缓存: 分析器: 优化器: 执行器: 总结 前言: 很多人都在使用mysql数据库,但是很少有人能够说出来整个sql语句的执行过程是怎样的,如果不了解执行过程的话,就很难进行sql语句的优化处理,也很难设计出来优良的数据库表结构.这篇文章主要是讲解一下sql语句的执行过程. sql语句的执行过程: 客户端.连接器.分析器.优化器.执行器.存储引擎几个阶段. 连接器的作用:管理链接.权限验证的处理. 分析器的作用:词法分析.语法分析. 优化器的作用:执行计

  • Java 超详细讲解核心类Spring JdbcTemplate

    目录 JdbcTemplate概述 JdbcTemplate开发步骤 JdbcTemplate快速入门 Spring产生JdbcTemplate对象 JdbcTemplate的常用操作 修改操作 删除和查询全部操作 查询单个数据操作 本章小结 JdbcTemplate概述 它是spring框架中提供的一个对象,是对原始繁琐的Jdbc API对象的简单封装.spring框架为我们提供了很多的操作 模板类.例如:操作关系型数据的JdbcTemplate和HibernateTemplate,操作nos

  • Java超详细讲解类变量和类方法

    目录 1.static静态变量 2.类变量(静态变量的访问) 3.类方法 1.static静态变量 1.静态变量被同一个类的所有对象共享 2.static类变量在类加载的时候就生成使用 static保存在class实例的尾部,在堆中 3.和C语言C++有点像 package com.demo.static_; import java.sql.SQLOutput; public class childgeme { public static void main(String[] args) { C

  • Xcode使用教程详细讲解(全)

    Xcode使用教程详细讲解是本文要介绍的内容,Xcode是一个款强大的IDE开发环境,就像你在写Windows程序时需要VS2005一样 需要要Xcode为你写Mac程序提供环境.因此,如果你要成为Mac 程序的开发者,灵活运用Xcode工具是你必须做的第一步. 1)我们写程序时常常在源文件的头部添加copyright声明以及公司名称等等:而Xcode在创建文件时已经帮我们做了绝大部分工作,我们可能需要修改一下公司名称,因为xcode给不知道我们公司名称,它不可能预知一切,所以需要我们自己通过设

随机推荐