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. MD5 in JAVA

    using Apache Commons 需要引入org.apache.commons.codec.digest.DigestUtils这个包,pom.xml文件配置如下: <!-- https ...

  2. 【Maven】项目中没有resources目录

    在eclipse中创建maven项目,src/main/只有java没有resources目录 解决办法: 1.项目右键properties 2.Java Build Path 中移除JRE Syst ...

  3. 002-Apache Maven 构建生命周期

    Maven - 构建生命周期 什么是构建生命周期 构建生命周期是一组阶段的序列(sequence of phases),每个阶段定义了目标被执行的顺序.这里的阶段是生命周期的一部分. 举例说明,一个典 ...

  4. webpack教程(六)——分离组件代码

    先来运行一下webpack命令, 看到app.js才4k. 安装一下react npm install react --sava-dev 在app/index.js文件内引入react 运行webpa ...

  5. monogodb使用

    菜鸟教程有相关介绍,已经很详细. http://www.runoob.com/mongodb/mongodb-databases-documents-collections.html 网上找了一些博客 ...

  6. 红黑树的插入Java实现

    package practice; public class TestMain { public static void main(String[] args) { int[] ao = {5, 1, ...

  7. jvm系列 (五) ---类的加载机制

    类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...

  8. nhibernate教程(4)--条件查询(Criteria Query)

    NHibernate之旅(4):探索查询之条件查询(Criteria Query) 2008-10-16 18:20 by 李永京, 44341 阅读, 43 评论, 收藏,  编辑 本节内容 NHi ...

  9. 团队作业8——第二次项目冲刺(Beta阶段)5.25

    1.当天站立式会议照片 会议内容: 本次会议为第六次会议 本次会议在陆大楼3楼召开,本次会议内容: ①:检查总结上次任务完成情况 ②:安排今天的分工 ③:对昨天的问题进行讨论 ④:遇到困难,及时群里反 ...

  10. Windows环境下JDK的下载与安装

    根据极客学院上的网课做的学习笔记,网课地址:http://www.jikexueyuan.com/course/205.html 1.首先检查一下本机是否有安装java.按win+R,在弹出窗口中输入 ...