联结是利用SQL的SELECT能执行的最重要的操作。为了提高存储的有效性和避免数据冗余,往往会将有关联的数据存储在好几张表中,那么怎样用一条SELECT语句就能检索出这些数据呢?

答案是JOIN(联结)。在一条SELECT语句中,我们可以联结多张表返回一组数据。

联结的本质是主表中符合条件的每一行与附表中符合条件的每一行进行配对,假如没有WHERE子句或联结条件,则主表中每一行将与附表中的每一行配对,总共会返回的行数是main_table_row_num * attach_table_row_num。如果主表和附表中包含的行数非常多,那么就有必要在WHERE子句中加入筛选条件,这样会大大减少不必要的配对。

联结主要有4种,分别是INNER JOIN(内联结)、LEFT JOIN(左联结)、RIGHT JOIN(右联结)、CROSS JOIN(叉联结)。

为了能清楚地说明这4种联结,我准备了如下示例数据:

一个product表,用来保存商品的名称、价格和供应商ID,一个vendor表,用来保存供应商ID,供应商名称。product表和vendor表之间通过product.vendor_id = vendor.id进行关联。

创建2个表:

CREATE TABLE product(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR() NOT NULL,
price INT UNSIGNED NOT NULL,
vendor_id INT UNSIGNED NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE vendor1(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR() NOT NULL,
PRIMARY KEY (id)
);

插入数据:

INSERT INTO product (name,price,vendor_id) VALUES('bread', , );
INSERT INTO product (name,price,vendor_id) VALUES('beer', , );
INSERT INTO product (name,price,vendor_id) VALUES('vegetables', , );
INSERT INTO product (name,price,vendor_id) VALUES('beef', , );
INSERT INTO product (name,price,vendor_id) VALUES('noodles', , );
INSERT INTO product (name,price,vendor_id) VALUES('fish', , );
INSERT INTO product (name,price,vendor_id) VALUES('milk', , );
INSERT INTO product (name,price,vendor_id) VALUES('water', , );
INSERT INTO vendor (name) VALUES('hellen');
INSERT INTO vendor (name) VALUES('ella');
INSERT INTO vendor (name) VALUES('matt');
INSERT INTO vendor (name) VALUES('jake');


说明:product表中保存商品信息,其中,有一部分商品是由店铺老板自己提供,所以这类商品没有供应商,用vendor_id = 0表示

1. INNER JOIN | 内联结

示例1-1:
找出product表中由ella提供的所有商品:

SELECT product.name, product.price, vendor.name FROM product
INNER JOIN vendor
ON product.vendor_id = vendor.id
WHERE vendor.name = 'ella';

结果:

总结:

INNER JOIN可以检索出符合条件(JOIN条件和WHERE条件等)的表product和表vendor的交集,如下图所示:

2. LEFT JOIN | 左联结

示例2-1:
列出product表中所有product,并列出其供应商

SELECT product.name, product.price, vendor.name FROM product
LEFT JOIN vendor
ON product.vendor_id = vendor.id;

结果:

总结:

LEFT JOIN 会检索出主表的所有记录,并且如果附表中的记录符合条件会附加到主表的记录中,主表与附表之间的关系如下图所示:

3. RIGHT JOIN | 右联结

示例3-1:
列出由ella和jake所提供的所有products

SELECT vendor.name as vendor_name,product.name as product_name FROM product
RIGHT JOIN vendor
ON product.vendor_id = vendor.id
WHERE vendor.name IN ('ella', 'jake');

结果:

总结:
RIGHT JOIN 会检索出附表的所有记录,并且如果主表中的记录符合条件会附加到附表的记录中,主表与附表之间的关系如下图所示:

4. CROSS JOIN | 叉联结

示例4-1:
列出由ella和hellen所提供的所有products

SELECT product.name as product_name, product.price, vendor.name as vendor_name
FROM product, vendor
WHERE product.vendor_id = vendor.id AND vendor.name IN ('ella', 'hellen');

结果:

CROSS JOIN 返回主表中符合条件的每一行与附表中符合WHERE条件的每一行的配对。

如果没有WHERE子句,可以更清楚看到CROSS JOIN的返回结果:

示例4-2:

SELECT * FROM product,vendor;

结果:

很明显,返回的结果是主表中的每一行与附表中的每一行的配对。

如果您觉得阅读本文对您有帮助,欢迎转载本文,但是转载文章之后必须在文章页面明显位置保留此段声明,否则保留追究法律责任的权利。

作  者:blog.jpdou.top

原文链接:http://blog.jpdou.top/mysql-join/

MySQL JOIN | 联结的更多相关文章

  1. MySQL的联结(Join)语法

    MySQL的联结(Join)语法 1.内联结.外联结.左联结.右联结的含义及区别:   在讲MySQL的Join语法前还是先回顾一下联结的语法,呵呵,其实连我自己都忘得差不多了,那就大家一起温习吧(如 ...

  2. MySQL内外联结

    一.内联结(INNER JOIN) MySQL内联结使用INNER JOIN将多个数据表t1,t2隔开,结果是t1里的每一个数据行将与t2里的每一个数据行组合. 逗号连接符.CROSS JOIN和JO ...

  3. MySQL -- 表联结

    创建联结:(使用WHERE联结)SELECTvend_name,prod_name,prod_priceFROMvendors,productsWHEREvendors.vend_id=product ...

  4. mysql join 查询图

    mysql join 查询,特别是对查两个表之间的差集,可以用table字段=null来做. 注意千万不是join on XX!=XX  ,这样出来的结果是错误的.

  5. SQL server 使用 内联结(INNER JOIN) 联结多个表 (以及过滤条件 WHERE, AND使用区别)

    INNER JOIN ……ON的语法格式: FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INN ...

  6. MySQL JOIN原理

    先看一下实验的两张表: 表comments,总行数28856 表comments_for,总行数57,comments_id是有索引的,ID列为主键. 以上两张表是我们测试的基础,然后看一下索引,co ...

  7. MySQL Join算法与调优白皮书(三)

    Batched Key Access Join Index Nested-Loop Join虽好,但是通过辅助索引进行链接后需要回表,这里需要大量的随机I/O操作.若能优化随机I/O,那么就能极大的提 ...

  8. 图解mysql join

    原文:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins 这个图文解释mysql join的各种技 ...

  9. 神奇的 SQL 之 联表细节 → MySQL JOIN 的执行过程(一)

    开心一刻 我:嗨,老板娘,有冰红茶没 老板娘:有 我:多少钱一瓶 老板娘:3块 我:给我来一瓶,给,3块 老板娘:来,你的冰红茶 我:玩呐,我要冰红茶,你给我个瓶盖干哈? 老板娘:这是再来一瓶,我家卖 ...

随机推荐

  1. 伪分布模式 hive查询

    [root@node1 ~]# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian ...

  2. [转]VS 2013 未找到与约束contractname Microsoft.VisualStudio.Utilities.IContentTypeRegistryService...匹配的导出

    前几天,将Visual studio 2013 update 3 升级到了update 5.打开原来的解决方案,出现了 未找到与约束 contractname Microsoft.VisualStud ...

  3. UCSC数据库数据调用cruzdb

    https://github.com/Wy2160640/cruzdb UCSC基因组数据库是注释,调节和变异以及越来越多的分类群的各种数据的重要资源. 该库旨在简化数据的利用,以便我们可以进行复杂的 ...

  4. Sublime Text 3下安装Emmet的问题

    电脑装了Sublime Text 3,顺便安装了很多插件,今天编写前端HTML代码时,想用起前端常用的Emmet插件的功能,Emmet插件已经安装好了,奈何输入简写格式,按“CTRL+E”,没有反应. ...

  5. 在Eclipse里面配置Struts2

    下面介绍在Eclipse里面配置Struts2 下载Struts2的压缩包 我下载的是2.3.32版本 解压之后如图所示 apps目录:Struts2的范例 docs目录:Struts2的文档 lib ...

  6. Spring JdbcTemplate+JdbcDaoSupport实例(和比较)

    首先,数据库是这样的,很简单. 当然,要引入spring的包,这里我全部导入了,省事. applicationContext.xml是这样的: <?xml version="1.0&q ...

  7. ant安装和配置

    一.安装ant到官方主页http://ant.apache.org下载新版(我用的1.9.2)的ant,得到的是一个apache-ant-1.9.2-bin.zip的压缩包.将其解压到你的硬盘上,例如 ...

  8. 深入浅出HTML PDF扫描版

    <深入浅出HTML>是一部讲述现代Web标准的优秀教程,彻底摒弃了过时的内容,始终贯彻三层分离的思想.书中结合实例讲述如何使用HTML.CSS设计符合现代Web标准的网页,并讲解了如何使用 ...

  9. Ansible Jinja2使用

    常用方法 ternary 根据结果的真假来决定返回值 - name: Set container backend to "dir" or "lvm" based ...

  10. (转)web端测试环境的搭建(tomcat)

    C/s架构,常见的QQ这种结构的程序是有服务器来提供服务的,客户端来使用服务:B/S架构不需要安装客户端,只需要浏览器就可以了例如QQ农场,BS架构的程序在更新维护的时候,不需要更新客户端,仅在服务器 ...