MySQL JOIN | 联结
联结是利用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
MySQL JOIN | 联结的更多相关文章
- MySQL的联结(Join)语法
MySQL的联结(Join)语法 1.内联结.外联结.左联结.右联结的含义及区别: 在讲MySQL的Join语法前还是先回顾一下联结的语法,呵呵,其实连我自己都忘得差不多了,那就大家一起温习吧(如 ...
- MySQL内外联结
一.内联结(INNER JOIN) MySQL内联结使用INNER JOIN将多个数据表t1,t2隔开,结果是t1里的每一个数据行将与t2里的每一个数据行组合. 逗号连接符.CROSS JOIN和JO ...
- MySQL -- 表联结
创建联结:(使用WHERE联结)SELECTvend_name,prod_name,prod_priceFROMvendors,productsWHEREvendors.vend_id=product ...
- mysql join 查询图
mysql join 查询,特别是对查两个表之间的差集,可以用table字段=null来做. 注意千万不是join on XX!=XX ,这样出来的结果是错误的.
- SQL server 使用 内联结(INNER JOIN) 联结多个表 (以及过滤条件 WHERE, AND使用区别)
INNER JOIN ……ON的语法格式: FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INN ...
- MySQL JOIN原理
先看一下实验的两张表: 表comments,总行数28856 表comments_for,总行数57,comments_id是有索引的,ID列为主键. 以上两张表是我们测试的基础,然后看一下索引,co ...
- MySQL Join算法与调优白皮书(三)
Batched Key Access Join Index Nested-Loop Join虽好,但是通过辅助索引进行链接后需要回表,这里需要大量的随机I/O操作.若能优化随机I/O,那么就能极大的提 ...
- 图解mysql join
原文:http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins 这个图文解释mysql join的各种技 ...
- 神奇的 SQL 之 联表细节 → MySQL JOIN 的执行过程(一)
开心一刻 我:嗨,老板娘,有冰红茶没 老板娘:有 我:多少钱一瓶 老板娘:3块 我:给我来一瓶,给,3块 老板娘:来,你的冰红茶 我:玩呐,我要冰红茶,你给我个瓶盖干哈? 老板娘:这是再来一瓶,我家卖 ...
随机推荐
- shell批量创建用户随机密码
批量创建用户随机密码企业面试题3:批量创建10个系统帐号usr01-usr10并设置密码(密码为随机8位字符串). #! /bin/bash . /etc/init.d/functions Path= ...
- Hive中SELECT TOP N的方法(order by与sort by的区别)
我想说的SELECT TOP N是取最大前N条或者最小前N条. Hive提供了limit关键字,再配合order by可以很容易地实现SELECT TOP N. 但是在Hive中order by只能使 ...
- vue.js基础学习(1)
一:v-cloak:解决浏览器闪烁,编译过程中不会显示,直到编译结束才显示. 用法:[v-cloak] { display: none;} <div v-cloak> {{ message ...
- JavaScript学习系列8 - JavaScript中的关系运算符
JavaScript中有8个关系运算符,分别是 ===, !===, ==, !=, <, <=, >, >= 1. 恒等运算符 (===) ===也叫做 严格相等运算符,它要 ...
- 3. 从零开始学CSRF
为什么要拿CSRF来当“攻击手法系列”的开头篇呢?因为CSRF/XSRF我个人喜爱他的程度已经超过XSS了.如果说XSS是一个老虎,那么CSRF就是隐藏在暗处的蛇. 相信现在很多人不明 ...
- JsonParse类
using System.Data; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using System; using Syst ...
- SAS笔记(2) RETAIN语句
本文重点: 使用RETIAN,INPUT在每次循环执行时保留上一次PDV中的变量值. SUM语句和SET语句会自动RETAIN变量. 1. RETAIN语句 1.1 Example 1 先来看看在DA ...
- VS2010 不显示 最近使用的项目 解决办法(转)
昨天重装了VS2010,然后开了项目看了下今天早上再打开发现起始页近使用项目列表是空白的,每次打开项目都要去到指定目录去找解决方案才能打开,感觉很麻烦,在网上找了下解决方案,解决步骤下:菜单 —— 运 ...
- OC 中的 weak 属性是怎么实现的?
OC 中的 weak 属性是怎么实现的,为什么在对象释放后会自动变成 nil?本文对这个问题进行了一点探讨.环境 mac OS Sierra 10.12.4 objc709参考答案 搜索后发现runt ...
- sql server 查询练习
需要建的四个表: 学生表 create table Student ( Sno varchar(20) not null primary key, Sname varchar(20) not null ...