1.  背景及原因

关系型数据库的一个基本原则是将不同细分数据放在单独的表中存储。这样做的好处是:

1).避免重复数据的出现

2).方便数据更新

3).避免创建重复数据时出错

例子:

有供应商信息和产品信息两部分。如果将他们放在一个表中。弊端有:

1). 同一供应商的所有数据所在行的供应商信息相同,即产生重复数据。

2). 在供应商信息变更时,如果更换联系方式或地址,需要在所有包含此供应商信息的行更新。

3). 在录入同一供应商的多个产品时,有可能会供应商信息不同,导致调取数据时无法使用。

通过将供应商和产品信息分别放在不同的表中,可以避免以上弊端。

1). 一个供应商只需一条记录,省时省空间。

2). 变更供应商信息时,只需变更一次。方便快捷不易出错。

3). 录入信息时,不会出错。

DB中存在如下几张表:

orders:

order_num, order_date, cust_id

venders:

vend_id, vend_name, vend_address, vend_contact

products:

prod_id, prod_name, vend_id, prod_price

customers:

cust_id, cust_name, cust_address, cust_city, cust_state

orderitems:

order_num, order_item, prod_id, quantity, item_price

2. 表的联结

由于以上原因,在调出多个表中信息时,就需要将多个表通过主键和外键联结。

联结的基本方法:1. 指出需要联结的表;2. 指出通过哪个字段联结。

例子:

需要供应商和所提供产品信息:

select vend_name, prod_name, prod_price #select fields
from vendors, products #from tables
where vendors.vend_id=products.vend_id #how to join tables;

3. 两种联结方法

除了上面的在where字句中创建联结,还可以使用关键字join ... on...

例如上面的语句还可写成:

select vend_name, prod_name, prod_price #select fields
from vendors inner join products #from tables
on vendors.vend_id=products.vend_id #how to join tables;

此处注意,在指定联结字段时,需要使用完全限定列名,既table.column的格式。

笛卡儿积:当没有制定联结字段时会出现笛卡儿积。既,被联结的两个表中任意一行都和另一个表中所有行联结。

4. 联结多个表

在一条SQL语句中可以联结任意多张表。但是要注意:联结表非常消耗数据库系统资源,所以一定要注意控制联结的使用。

一个例子:

select prod_name, vend_name, prod_price, quantity
from products, vendors, orderitems
where products.prod_id = orderitems.prod_id
and vendors.vend_id=products.vend_id
and orderitems = 20005;

5. 联结的类型

1). 内联结和外联结

内联结:查找出的行是通过两个表的相等测试的数据。inner join on

外联结:在联结是指定一个表,并反回其中所有行,无论是否通过相等测试。外联结包括左联结右联结。left/right outer join on

一个例子:检索系统中所有下了订单的客户id和订单数量

内联结:

select customers.cust_id, orders.order_num
from customers inner join orders
on customers.cust_id= orders.cust_id;

只有下了订单的客户信息会被检索到。

外联结:

select customers.cust_id, orders.order_num
from customers left outer join orders
on customers.cust_id= orders.cust_id;

left outer join左边的customers表中所有的行都会被检索到。不论客户是否下单。

左联结和右联结的区别:

左联结关键字的左边的表会被检索出所有行,右联结关键字右边的表会被检索出所有行。所以左联结和右联结可以轻易转换,在实现功能上没有区别。

2).自联结

在一些特定情况下,需要让一张表自己和自己做联结,就需要用到自联结。例如需要查出生产了产品ID为DTNTR的供应商的所有产品。

使用子查询:

select prod_id, prod_name
from products
where vend_id in (select vend_id
from products
where prod_id="DTNTR");

使用自联结:

select p1.prod_id, p2.prod_name
from products as p1 inner join products as p2
on p1.vend_id=p2.vend_id
and p2.prod_id="DTNTR";

3).自然联结

所有查找出的列都是唯一的,不会有一个行被输出两次。自然联结需要通过人工手动实现,没有公式或关键字能制定自然联结。

6. 有聚合函数的联结

联结可以和聚合函数一起使用。例如,需要检索出所有客户的订单数:

内连接:

select customers.cust_id, customers.cust_name,
count(orders.order_num) as num_ord
from customers inner join orders
on customers.cust_id inner join orders.cust_id
group by customers.cust_name;

检索出所有已下单客户的订单数。

外联结:

select customers.cust_id, customers.cust_name,
count(orders.order_num) as num_ord
from customers left outer join orders
on customers.cust_id inner join orders.cust_id
group by customers.cust_name;

检索出所有客户的订单数,包括没有订单数为0的客户。

7. 有关full join

MySQL不支持full join 关键字,但是可以通过union间接实现。

full join: 既将两张表通过连接字段连接,两张表的行都会保留无论是否经过了相等测试。

通过下面的MySQL中的替代方式也可以理解full join的原理:

select products.prod_name,products.prod_price,venders.vend_name,venders.vend_contact
from venders
left outer join products
on venders.vend_id = products.vend_id
union
select products.prod_name,products.prod_price,venders.vend_name,venders.vend_contact
from venders
right outer join products
on venders.vend_id = products.vend_id

MySQL自学笔记_联结(join)的更多相关文章

  1. MySQL自学笔记_聚集函数

    1. 使用场景 很多时候我们需要查找数据库中符合特定条件的数据的计数.最大值.最小值.平均值等一个数字,并需要要导出所有相关数据明细.此时就需要用到聚集函数. 而返回所有数据明细会占用数据库资源和网络 ...

  2. Mysql自学笔记

    SQL(strucut query language) DDL (数据库定义语言)DML (数据库操作语言)DCL (数据库的控制语言)DTL (数据库的高级语言)查看版本的函数select vers ...

  3. MySQL学习笔记_时间,多表更新,数据库元数据

    MySQL技术内幕一.MySQL基础知识1.1.显示表中的列SHOW COLUMNS FROM order_info like 'order%'1.2.显示表SHOW TABLES LIKE 'ord ...

  4. MySQL 自学笔记_Union(组合查询)

    1. Union查询简介 组合查询:有时在使用select语句进行数据查询时,想要将多个select语句在一个查询结果中输出,此时就需要使用Union关键字. Union的使用方法:用union将多个 ...

  5. Python自学笔记_

    1. if语句 判断语句. 1 a=2 2 b=3 3 if a>b: 4 print("a>b") 5 else: 6 print("a<b" ...

  6. mysql basic operation,mysql总结,对mysql经常使用语句的详细总结,MySQL学习笔记

    mysql> select * from wifi_data where dev_id like "0023-AABBCCCCBBAA" ; 1.显示数据库列表.show d ...

  7. MYSQL基础笔记(五)- 练习作业:站点统计练习

    作业:站点统计 1.将用户的访问信息记录到文件中,独占一行,记录IP地址 <?php //站点统计 header('Content-type:text/html;charset=utf-8'); ...

  8. MySQL入门笔记

    MySQL入门笔记 版本选择: 5.x.20 以上版本比较稳定 一.MySQL的三种安装方式: 安装MySQL的方式常见的有三种: ·          rpm包形式 ·          通用二进制 ...

  9. MySQL入门笔记(二)

    MySQL的数据类型.数据库操作.针对单表的操作以及简单的记录操作可参考:MySQL入门笔记(一) 五.子查询   子查询可简单地理解为查询中的查询,即子查询外部必然还有一层查询,并且这里的查询并非仅 ...

随机推荐

  1. Django - CRM项目(2)Q查询(模糊查询)

    一.CRM项目(2) 利用Q查询中的q对象完成条件筛选功能. 批量删除.公户转私户功能. 新增一张跟进记录表ConsultRecord,迁移数据库并添加测试数据,实现跟进记录列表页面. 客户列表新增跟 ...

  2. Unity UGUI暂停按钮切换图片代码

    using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; ...

  3. Spark Mllib里如何生成KMeans的训练样本数据、生成线性回归的训练样本数据、生成逻辑回归的训练样本数据和其他数据生成

    不多说,直接上干货! 具体,见 Spark Mllib机器学习(算法.源码及实战详解)的第2章 Spark数据操作

  4. 【Linux】linux下tar.gz、tar、bz2、zip等解压缩、压缩命令小结

    Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的.生成tar包后,就可以用其它的程序来进 行压缩了,所以首先就来讲讲ta ...

  5. vue resource patch方法的传递数据 form data 为 [object Object]

    今天在测试 iblog 登录时,传送过去的数据总是 [object Object],以至于后台识别不出来. vue 使用了 vueResource 组件,登录方法为 patch. 经过探索,终于在官网 ...

  6. 玩转spring ehcache 缓存框架

    一.简介 Ehcache是一个用Java实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案.同时ehcache ...

  7. addin修改启动路径

  8. 【MFC】将当前的日期转化为1970年开始的秒计数

    CTime time1 = CTime::GetCurrentTime(); int nTSeconds = time1.GetTime(); CTime time2(,,,,,); nTSecond ...

  9. jQuery-安装方法(2类)

    一.下载到本地,调用本地jQuery库 下载地址:http://jquery.com/download/ 共有两个版本的 jQuery 可供下载: 1.精简版:用于实际的网站中,已被精简和压缩. 2. ...

  10. (转) HTTP Request header

    HTTP Request header 当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基 ...