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入门笔记(一) 五.子查询 子查询可简单地理解为查询中的查询,即子查询外部必然还有一层查询,并且这里的查询并非仅 ...
随机推荐
- 在邮箱服务器上执行Powershell命令Get-MessageTrackingLog 报错
开启对应的服务即可. 中文环境: 英文环境:
- 牛客练习赛43F(推式子)
要点 题目链接 1e18的数据无法\(O(n)\)的容斥,于是推式子,官解,其中式子有点小错误 不必预处理mu,直接按照素数的个数判断正负即可 #include <bits/stdc++.h&g ...
- RMAN restore fails with ORA-01180: can not create datafile 1 (文档 ID 1265151.1)
http://blog.itpub.net/26655292/viewspace-2131269/ ########Q&A issue1:ORA-01180: can not create d ...
- windows下显示隐藏的文件
文件--文件夹选项---查看---高级设置----隐藏文件和文件夹----显示隐藏的文件.文件夹和驱动器
- Java面向对象_增强for可变参数与代码块
1.foreach循环 for(类型 变量名称:数组或集合){ //输出操作 } 2.可变参数:根据需要自动传入任意个数的参数,就是可变参数. 语法:返回值类型 方法名称(数据类型...参数名称){ ...
- log(A^B) = BlogA
令 x = logA, y = logB, z=log(AB) .2x = A, 2y = B, 2z = AB, 则有 2z = AB = (2x)^(2y) = 2x(2^y) ,有z = x*2 ...
- SQL中改变列的数据类型
一.该列非主键.无default约束 直接更新: alter table 表名 alter column 列名 数据类型 二.该列为主键列.无default约束 (1)删除主键 alter table ...
- 《疯狂动物城》主题曲《TryEverything》中文翻译
<疯狂动物城>主题曲<TryEverything>夏奇拉激情献唱,很多事情是需要是试试,不试试就不知道可以成功. Oh oh oh oh oooh 哦哦哦哦哦 Oh oh oh ...
- cairo-dock天气位置代码
cairo-dock天气位置代码: 城市: 北京CHXX0008哈尔滨CHXX0046长春CHXX0010沈阳CHXX0119大连CHXX0019天津CHXX0133呼和浩特CHXX0249乌鲁木齐C ...
- SpringMVC配置文件 中 mvcview-controller 标签的使用
一.<mvc:view-controller path=""/>标签的作用 工程WEB-INF目录下面的JSP页面,我们知道是不能直接使用URL访问到.需要通过控制器转 ...