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入门笔记(一) 五.子查询 子查询可简单地理解为查询中的查询,即子查询外部必然还有一层查询,并且这里的查询并非仅 ...
随机推荐
- BZOJ 2462 [BeiJing2011]矩阵模板 矩阵哈希
昨天卡了一天常数...然后发现吧$unsigned\space long\space long$改成$unsigned$就可以过了$qwq$ 先把每一行的前缀哈希求出,然后再竖着把每个前缀哈希值哈希起 ...
- Codeforces Round #365 (Div. 2) B
Description Little Mishka is a great traveller and she visited many countries. After thinking about ...
- onbeforeunload与onunload事件
Onunload,onbeforeunload都是在刷新或关闭时调用,可以在<script>脚本中通过 window.onunload来指定或者在<body>里指定.区别在于o ...
- Java多线程与并发——生产者与消费者应用案例
多线程的开发中有一个最经典的操作案例,就是生产者-消费者,生产者不断生产产品,消费者不断取走产品. package com.vince; /** * 生产者与消费者案例 * @author Admin ...
- Java多线程与并发——线程同步
1.多线程共享数据 在多线程的操作中,多个线程有可能同时处理同一个资源,这就是多线程中的共享数据. 2.线程同步 解决数据共享问题,必须使用同步,所谓同步就是指多个线程在同一时间段内只能有一个线程执行 ...
- jdbc 开启事务
package com.itheima.tx; import java.sql.Connection; import java.sql.PreparedStatement; import java.s ...
- 关于js框架 dwz 与 yii的的分页 以及筛选的结合
此为jicheng1014 原创....地址为http://jicheng1014.cnblogs.com dwz是一个不错的前端框架 但是 注意 所有的后端 都是要自己写的 常见的应用是 ...
- phpcms文件结构
主要目录部分 /admin 管理后台目录 -- /skin/ 后台样式 -- /templates/ 后台样式模板 /api api接口 /corpandresiz ...
- jQuery的parent和parents和closest区别
1.parent是指取得一个包含着所有匹配元素的唯一父元素的元素集合.2.parents则是取得一个包含着所有匹配元素的祖先元素的元素集合(不包含根元素).可以通过一个可选的表达式进行筛选.3.clo ...
- HTML 笔记之 HTML 元素的概念
HTML 不是编程语言,它是一种标记语言 HTML 中常见的几个名词是 元素. 标签(开始标签和结束标签). 属性. 元素内容 这篇文章将要介绍的是 HTML 元素的概念 元素的概念 例子: < ...