MySQL自学笔记_联结(join)
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)的更多相关文章
- MySQL自学笔记_聚集函数
1. 使用场景 很多时候我们需要查找数据库中符合特定条件的数据的计数.最大值.最小值.平均值等一个数字,并需要要导出所有相关数据明细.此时就需要用到聚集函数. 而返回所有数据明细会占用数据库资源和网络 ...
- Mysql自学笔记
SQL(strucut query language) DDL (数据库定义语言)DML (数据库操作语言)DCL (数据库的控制语言)DTL (数据库的高级语言)查看版本的函数select vers ...
- MySQL学习笔记_时间,多表更新,数据库元数据
MySQL技术内幕一.MySQL基础知识1.1.显示表中的列SHOW COLUMNS FROM order_info like 'order%'1.2.显示表SHOW TABLES LIKE 'ord ...
- MySQL 自学笔记_Union(组合查询)
1. Union查询简介 组合查询:有时在使用select语句进行数据查询时,想要将多个select语句在一个查询结果中输出,此时就需要使用Union关键字. Union的使用方法:用union将多个 ...
- Python自学笔记_
1. if语句 判断语句. 1 a=2 2 b=3 3 if a>b: 4 print("a>b") 5 else: 6 print("a<b" ...
- mysql basic operation,mysql总结,对mysql经常使用语句的详细总结,MySQL学习笔记
mysql> select * from wifi_data where dev_id like "0023-AABBCCCCBBAA" ; 1.显示数据库列表.show d ...
- MYSQL基础笔记(五)- 练习作业:站点统计练习
作业:站点统计 1.将用户的访问信息记录到文件中,独占一行,记录IP地址 <?php //站点统计 header('Content-type:text/html;charset=utf-8'); ...
- MySQL入门笔记
MySQL入门笔记 版本选择: 5.x.20 以上版本比较稳定 一.MySQL的三种安装方式: 安装MySQL的方式常见的有三种: · rpm包形式 · 通用二进制 ...
- MySQL入门笔记(二)
MySQL的数据类型.数据库操作.针对单表的操作以及简单的记录操作可参考:MySQL入门笔记(一) 五.子查询 子查询可简单地理解为查询中的查询,即子查询外部必然还有一层查询,并且这里的查询并非仅 ...
随机推荐
- fastJson Gson对比及java序列化问题
一个案例 POJO没有set方法, 造成反序列化时出现NPE问题.实际场景:POJO是第三方提供的,final public class XJSONTest { public static void ...
- jquery——属性操作、特殊效果
1. attr().prop() 取出或者设置某个属性的值 <!DOCTYPE html> <html lang="en"> <head> &l ...
- (转)不看绝对后悔的Linux三剑客之sed实战精讲
不看绝对后悔的Linux三剑客之sed实战精讲 原文:http://blog.51cto.com/hujiangtao/1923718 二.Linux三剑客之sed命令精讲 1,前言 我们都知道,在L ...
- Maven的学习资料收集--(一)环境搭建
这几天在做项目的时候用到了maven,但是自己没有从来没有接触过,所以咋网上找资料,终于找到了一下的资料,这个是别人总结的,我只是转载过来积累.请尊重原创. 官网地址:http://maven.apa ...
- HTML <pre> 标签
需求 错落有致的规则说明 ps.我真的是一个后端开发... pre 元素中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体.
- VS2015配置使用Sqlite以及EF6框架记录
项目中需要使用到Sqlite本地数据库保存数据,以防止离线情况下设备的正常使用. 一.下载vs2015下的sqlite插件,并安装 插件下载页面:http://system.data.sqlite.o ...
- 自己动手实现STL 03:内存基本处理工具(stl_uninitialized.h)
一.前言 前面两篇已经编写了内存配置器和建构解构工具函数.这里,就准备编写并介绍下内存基本处理工具函数.比如uninitialized_copy().uninitialized_copy和 unini ...
- spring boot 监控与管理(actuator)
Spring POMs 中提供了一个特殊的依赖模块,即spring-boot-starter-actuator,我们只需要在我们的POM中添加依赖即可 <!-- 监控 管理 --> < ...
- servlet和jsp存值和取值的方式
在servlet和jsp中存值和取值的方式由两种 1种是setAttribute和getAttribute 2种是c:forEach
- Eucalyptus简介
1.Eucalyptus是什么? Eucalyptus n.桉树 Eucalyptus is a Linux-based software architecture that implements ...