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. easyui+ztree 后台管理系统模板

    用easyui+ztree做了个后台管理系统模板,效果图: 下载地址: csdn:http://download.csdn.net/detail/jackpay/6744505 github:http ...

  2. noip普及组2007 Hanoi双塔问题

    Hanoi双塔问题 描述 给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的.现要将这些圆盘移到C柱上,在移动 ...

  3. 【Ubuntu 16】 wifi连接 并解决无桌面图标问题

    笔记本上装了win10和ubuntu16双系统,ubuntu16有半年多没使用了,今天一登录成功后,没有桌面啦,一个干净的壁纸映入眼帘,真操蛋. 上网搜索后总结:应该是应用软件中心出了问题,可是,没法 ...

  4. centos 创建用户组及用户

    用户及用户组存放文件 1./etc/passwd 其中每一行记录对应着一个用户,每行记录又被冒号(:)分隔为7个字段,其格式和具体含义如下: [cpp] view plaincopyprint?在CO ...

  5. 区别jquery对象和dom对象及转换方法

    一.jquery对象 由$() 获取,例如 var div = $("#id"); 这个div是jquery对象,它里面没有dom对象自带的方法.常见的dom对象自带的方法, 例如 ...

  6. 关于i++和++i

    初学Java,经常看到i++和++i的一些问题,在此整理一下. 首先看下面一个小程序: public class atest{ public static void main(String args[ ...

  7. JRE 和 JDK 的区别

    JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库.是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的.   JDK顾名思义是java开发 ...

  8. Python常用库大全

    环境管理 管理 Python 版本和环境的工具 p – 非常简单的交互式 python 版本管理工具. pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. v ...

  9. JS源生代码“增删改查”之增

    51呢最近在做一个管理数据的,第一次接触到用JS的源代码去实现一些功能,才知道网页里的许多功能都是依赖于“增删改查”完成的,下面的几张图片就是对于增的演示: 下面是有关HTML的代码:这个主要是弹窗部 ...

  10. 车牌识别OCR—易泊时代智慧城市解决方案模块

    牌识别(License Plate Recognition,LPR) 是视频图像识别技术在智能交通领域中的一个模块.车牌识别运用OCR技术,将视频流或图片中的汽车牌照从复杂的应用场景中提取并识别出来, ...