1、基本连接

不同类型的数据,存储在多个表中,而所谓多表连接,就是将多个表联合返回一组输出。

1.1 等值连接

基本的连接方式非常简单,只需要在WHERE子句中规定如何关联即可,如下:
SELECT
vend_name,
prod_name,
prod_price
FROM
vendors,
products
WHERE
vendors.vend_id = products.vend_id
ORDER BY
vend_name, prod_name;
11
 
1
SELECT 
2
  vend_name,
3
  prod_name,
4
  prod_price
5
FROM
6
  vendors, 
7
  products
8
WHERE
9
  vendors.vend_id = products.vend_id
10
ORDER BY
11
  vend_name, prod_name;

最终的输出结果中,会包含另一张表products中的prod_name和prod_price两个列。

在以上的示例中,我们指定了WHERE子句中 vendors.vend_id = products.vend_id ,所以在连接两个表时,你实际上做的是将第一个表中的每一行与第二个表中的每一行配对,WHERE子句作为过滤条件。

这种方式,也叫做等值连接,也称为内部连接(INNER JOIN)。当两个关系不存在公共属性(即字段名称和类型完全相同)时,以取值具有可比性的同类型属性为基础进行连接。

实际上,你也可以用稍微不同的格式来进行,以下和之前示例的效果是一样的:
SELECT
vend_name,
prod_name,
prod_price
FROM
vendors INNER JOIN products ON vendors.vend_id = prodcuts.vend_id;
6
 
1
SELECT
2
  vend_name,
3
  prod_name,
4
  prod_price
5
FROM
6
  vendors INNER JOIN products ON vendors.vend_id = prodcuts.vend_id;

多表连接中对于表连接的数量是没有限制的,规则也都相同,如连接三个表,以上两种方式分别为:
SELECT
vend_name,
prod_name,
prod_price,
quantity
FROM
vendors,
products,
orderitems
WHERE
vendors.vend_id = products.vend_id
AND
orderitems.prod_id = products.prod_id
ORDER BY
vend_name, prod_name;
15
 
1
SELECT
2
  vend_name,
3
  prod_name,
4
  prod_price,
5
  quantity
6
FROM
7
  vendors, 
8
  products,
9
  orderitems
10
WHERE
11
  vendors.vend_id = products.vend_id
12
  AND
13
  orderitems.prod_id = products.prod_id
14
ORDER BY
15
  vend_name, prod_name;

SELECT
vend_name,
prod_name,
prod_price,
quantity
FROM
(vendors INNER JOIN products ON vendors.vend_id = prodcuts.vend_id)
INNER JOIN orderitems ON orderitems.prod_id = products.prod_id;
9
 
1
SELECT
2
  vend_name,
3
  prod_name,
4
  prod_price,
5
  quantity
6
FROM
7
  (vendors INNER JOIN products ON vendors.vend_id = prodcuts.vend_id)
8
    INNER JOIN orderitems ON orderitems.prod_id = products.prod_id;
9
  

1.2 笛卡儿积

由没有连接条件的表关系返回的结果为笛卡儿积。检索出来的行的数目将是第一个表中的行数乘以第二个表中的行数。
SELECT
vend_name,
prod_name,
prod_price
FROM
vendors,
products
ORDER BY
vend_name, prod_name;
9
 
1
SELECT
2
  vend_name,
3
  prod_name,
4
  prod_price
5
FROM
6
  vendors,
7
  products
8
ORDER BY
9
  vend_name, prod_name;

简单地说,第一个表中的每一行会和第二个表中的每一行一一匹配为新的行筛出。

这种表往往并不是我们所需要的,因为表间关系混乱,每条数据进行了无差别匹配,包括了它从业务逻辑上根本就不应该对应的东西。

所以,在进行表连接时一定要保证WHERE子句。



2、高级联结

2.1 自连接

自连接即两个相同的表的连接,往往作为外部语句用来替代从相同表中检索数据时使用的子查询语句。

如下例为,加入你发现某物品(ID为DTNTR)存在问题,因此想知道该产品供应商的其他产品是否也存在同样的问题:
SELECT
prod_id,
prod_name
FROM
products
WHERE
vend_id =
(SELECT vend_id FROM products WHERE prod_id = 'DTNTR');
8
 
1
SELECT
2
  prod_id,
3
  prod_name
4
FROM
5
  products
6
WHERE
7
  vend_id = 
8
  (SELECT vend_id FROM products WHERE prod_id = 'DTNTR');

使用自连接的方式:
SELECT
p1.prod_id,
p1.prod_name
FROM
products AS p1,
products AS p2
WHERE
p1.vend_id = p2.vend_id
AND
p2.prod_id = 'DTNTR';
10
 
1
SELECT
2
  p1.prod_id,
3
  p1.prod_name
4
FROM
5
  products AS p1,
6
  products AS p2
7
WHERE
8
  p1.vend_id = p2.vend_id
9
  AND
10
  p2.prod_id = 'DTNTR';

2.2 自然连接 NATURAL JOIN

我们在说到内连接,即等值连接的时候,会返回所有的数据,甚至相同的列多次出现。

而自然连接,就是排除了那些多次出现的列,使每个列只返回一次。即“自然连接”和“内连接”的区别,在于对“重合的相同的部分”处理方式不同:
  • "natural join 自然连接" 的处理方式:既然重复了,就丢掉一份,好比distinct
  • “inner join 内连接” 的处理方式:虽然重复,但两份都保留

2.3 外部连接 LEFT/RIGHT OUTER JOIN

许多连接是将一个表中的行,与另一个表中的行相关联,某些情况下需要包含没有关联行的行,这时候就要用到外部连接。

简单来说,一般的如自然连接和等值连接,两个表中只有相互匹配的行才会组成新的行放在结果表中,没有匹配的行不论在第一个表还是在第二个表它最终都会信息丢失,不会出现在最终的结果表中。而外部连接,就可以保留这部分信息。

如为了检索所有客户,包括那些没有订单的客户,可以用如下:
SELECT
customers.cust_id,
orders.order_num
FROM
customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id;
5
 
1
SELECT
2
  customers.cust_id,
3
  orders.order_num
4
FROM
5
  customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id;

使用OUTER JOIN语法时,必须使用RIGHT或LEFT,两者的区别在于,以哪边的表为主。例如左连接,在结果表中,则左边表的行全部保留,而右边表的行则是以是否满足自然连接为依据,不匹配的会丢失。



3、组合查询 UNION

我们大多数的操作,都是从一个或多个表返回数据的单条SELECT语句。

MySQL允许我们执行多条SELECT语句,而把它们的结果作为单个查询结果集返回。这样的组合查询通常称之为并(union)或复合查询(compound query)。

UNION的使用很简单,只需要给出每条SELECT语句,并在各条之间放上关键字UNION。

如下例,需要价格小于等于5的所有物品的列表,而且还想包括供应商1001和1002生产的所有物品(不考虑价格),当然你可以使用WHERE子句来完成,这里我们使用UNION:
(
SELECT
vend_id,
prod_id,
prod_price
FROM
products
WHERE
prod_price <= 5
)
UNION
(
SELECT
vend_id,
prod_id,
prod_price
FROM
products
WHERE
vend_id IN (1001, 1002)
);
21
 
1
(
2
SELECT
3
  vend_id,
4
  prod_id,
5
  prod_price
6
FROM
7
  products
8
WHERE
9
  prod_price <= 5
10
)
11
UNION
12
(
13
SELECT
14
  vend_id,
15
  prod_id,
16
  prod_price
17
FROM
18
  products
19
WHERE
20
  vend_id IN (1001, 1002)
21
);

当然,如果用WHERE子句的话,方式如下:
SELECT
vend_id,
prod_id,
prod_price
FROM
products
WHERE
prod_price <= 5
OR
vend_id IN (1001, 1002);
 
1
SELECT
2
  vend_id,
3
  prod_id,
4
  prod_price
5
FROM
6
  products
7
WHERE
8
  prod_price <= 5
9
  OR
10
  vend_id IN (1001, 1002);

在这个例子中,UNION可能使用起来更复杂,但是对于更复杂的过滤条件,或者从多个表(而不是单个表)中检索数据的情形,使用UNION可能会使处理更简单,逻辑更清晰。

另,使用UNION有几条规则需要注意:
  • UNION必须由两条或以上的SELECT语句组成
  • 每个查询必须包含相同的列、表达式或聚集函数
  • 列数据类型必须兼容
  • UNION会默认自动取消各SELECT结果中重复多余的结果,如果需要保留,使用UNION ALL关键字
  • 结果集无法出现一部分使用一种方式排序,另一部分使用其他方式排序,只能使用一条ORDER BY


《MySQL必知必会》[02] 多表联合查询的更多相关文章

  1. 《MySQL必知必会》官方提供的数据库和表

    数据用于配合<MySQL必知必会>(MySQL Crash Course)这本书使用,配套SQL文件也可在Ben Forta网站下载. Ben Forta网址:http://forta.c ...

  2. MySQL必知必会-官方数据库表及SQL脚本导入生成

    最近在复习SQL语句,看的是MySQL必知必会这本书,但是发现附录中只有表设计,没有表的具体数据.所以在学习相应的语句中体验不是很好,去网上查了数据库的内容,自己慢慢导入到了数据库中.把表放出来作为参 ...

  3. mysql学习--mysql必知必会1

     例如以下为mysql必知必会第九章開始: 正則表達式用于匹配特殊的字符集合.mysql通过where子句对正則表達式提供初步的支持. keywordregexp用来表示后面跟的东西作为正則表達式 ...

  4. mysql学习--mysql必知必会

      上图为数据库操作分类:     下面的操作參考(mysql必知必会) 创建数据库 运行脚本建表: mysql> create database mytest; Query OK, 1 row ...

  5. MySQL使用和操作总结(《MySQL必知必会》读书笔记)

    简介 MySQL是一种DBMS,即它是一种数据库软件.DBMS可分为两类:一类是基于共享文件系统的DBMS,另一类是基于客户机——服务器的DBMS.前者用于桌面用途,通常不用于高端或更关键应用. My ...

  6. django基础之day04,必知必会13条,双下划线查询,字段增删改查,对象的跨表查询,双下划线的跨表查询

    from django.test import TestCase # Create your tests here. import os import sys if __name__ == " ...

  7. 《MySQL 必知必会》读书总结

    这是 <MySQL 必知必会> 的读书总结.也是自己整理的常用操作的参考手册. 使用 MySQL 连接到 MySQL shell>mysql -u root -p Enter pas ...

  8. 《MySQL必知必会》[01] 基本查询

    <MySQL必知必会>(点击查看详情) 1.写在前面的话 这本书是一本MySQL的经典入门书籍,小小的一本,也受到众多网友推荐.之前自己学习的时候是啃的清华大学出版社的计算机系列教材< ...

  9. mysql必知必会系列(一)

    mysql必知必会系列是本人在读<mysql必知必会>中的笔记,方便自己以后查看. MySQL. Oracle以及Microsoft SQL Server等数据库是基于客户机-服务器的数据 ...

随机推荐

  1. 物体自由落体动态模拟(Linear Subspace)

    三维物体变形方法赋予了模拟物体的动态特性,但是随着物体模型的复杂度慢慢增加,对高质量的实时变形方法也提出了更高的要求.对于高精度的大型三维网格而言,通常会设计一个低精度的子网格,并构建子网格与原始网格 ...

  2. 关于MVC项目中的主管放行

    一线程序员和 sa 总是相恨相杀,这话确实不假,吐槽这里就不多讲,项目快开发完的时候,让之前各个模块的增删改的操作全部都先放入对应的临时表(增加一状态栏位Status,来表示增.删.改)中,然后在主管 ...

  3. 在 Android 中如何优雅地配置私密信息

    在实际的项目开发中,经常会用到一些第三方的 SDK ,而使用这些 SDK 基本上都是需要配置 APPKEY 或 APPSECRET 等信息.此外 APP 打包时需要 KEYSTORE , STOREP ...

  4. 【转】深入探讨 Java 类加载器

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html 类加载器是 Java 语言的一个创新,也是 Java ...

  5. SQL用法笔记

    1.更改当前记录以外的数据的xh自动加1(MySQL字段为int) String sql = "UPDATE t_readtext as tr SET xh = xh +1\n" ...

  6. CSS选择器大汇总

    CSS选择器是学习CSS以及Web编程的基础. 整理出常用的CSS选择器,供自己和大家一起学习. 基本选择器 * /*通用元素选择器,匹配页面任何元素(这也就决定了我们很少使用)*/ #id /*id ...

  7. .NET平台微服务项目汇集

    最近博客园出现了一篇文章<微服务时代之2017年五军之战:Net PHP谁先死>,掀起了一波撕逼,作者只是从一个使用者的角度来指点江山,这个姿势是不对的..NET Core就是专门针对模块 ...

  8. k-临近算法学习

    本章主要内容: k-临近算法是通过对象本身的特征将对象划分到某一类型中去,比如电影中的题材类型的分类是,可能就会考虑到电影中出现的镜头出现的次数的多少将电影划分为动作电影,爱情电影等等,本次的随笔参考 ...

  9. 线性代数-矩阵-转置 C和C++的实现

    原理解析: 本节介绍矩阵的转置.矩阵的转置即将矩阵的行和列元素调换,即原来第二行第一列(用C21表示,后同)与第一行第二列(C12)元素调换位置,原来c31与C13调换.即cij与cji调换 . (此 ...

  10. Jmeter代理服务器设置

    上一篇我们讲了代理工作的原理,这次我们就来分享下,如何来设置代理. (一)设置Jmeter之web代理,操作步骤这里就直接用动图代替了. 第一步:设置Jmeter的代理,添加Http代理服务器 第二步 ...