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入门笔记(一) 五.子查询 子查询可简单地理解为查询中的查询,即子查询外部必然还有一层查询,并且这里的查询并非仅 ...
随机推荐
- POJ2758 Checking the Text 哈希
注意到插入次数挺少的,于是每次暴力重构,然后哈希+二分 #include<cstdio> #include<iostream> #include<algorithm> ...
- 华东交通大学2017年ACM“双基”程序设计竞赛 1008
Problem Description 长度为 n 的序列,把它划分成两段非空的子序列,定义权值为:两段子序列的最大值的差的绝对值.求可能的最大的权值.数据范围:2 <= n <= 10^ ...
- linux下.exe文件的安装与使用
1安装wine 2 安装exe软件:下载应用软件.exe,然后点击右键用wine打开/或者在终端中wine 应用软件.exe即能安装. 卸载exe可以右键点击安装软件中uninstall.exe-用w ...
- (转)Linux硬链接、软链接及inode详解
inode 文件储存在硬盘上,硬盘的最小存储单位叫做“扇区”(Sector).每个扇区储存512字节(相当于0.5KB). 操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读 ...
- hide(),show()
var newstypevalue =$("#newstype option:selected").val(); if(newstypevalue=='0'){ ...
- cocos
cocos compile -p android --android-studio --app-abi=armeabi-v7a ./adb kill-server&& ./adb se ...
- 【Unity3D】用C#读取INI配置文件
由于在C#并没有提供专门读取INI文件的API,所以需要间接调用C++的API来进行读取. using System; using System.Collections.Generic; using ...
- Hadoop源生实用工具之distcp
1 概览 DistCp(Distributed Copy)是用于大规模集群内部或者集群之间的高性能拷贝工具. 它使用Map/Reduce实现文件分发,错误处理和恢复,以及报告生成. 它把文件和目录的列 ...
- 关于Mdi窗口-父窗口上的控件把子窗口的挡住的问题
using System.Runtime.InteropServices; [DllImport("user32")] public static extern int SetPa ...
- 【web】movie review——静态页面训练、css训练
实现样式要求: image: banner.png: generaloverview.png: background.png: bannerbackground.png: rottenbig.png: ...