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入门笔记(一) 五.子查询 子查询可简单地理解为查询中的查询,即子查询外部必然还有一层查询,并且这里的查询并非仅 ...
随机推荐
- 练习十七:python辨别数据类型
关于python辨别数据类型可以用python type()方法,那么想要查看一串字符中每项类型,并逐一输出要怎么处理?看下我是怎么处理的 习题要求:输入一行字符,分别统计其中英文字母.数字.空格.和 ...
- oracle 中的null与''
1.先看看Null与''在oracle中的表现 C:\Users\zen>sqlplus hr/hr SQL Production :: Copyright (c) , , Oracle. Al ...
- Python 装饰器的形成过程
装饰器 定义:本质是函数,(装饰其他函数),即为其他函数添加附加功能. 原则: 1.不能修改被装饰的函数的源代码: 2.不能修改被装饰的函数的调用方式. 实现装饰器知识储备: ...
- vue resource patch方法的传递数据 form data 为 [object Object]
今天在测试 iblog 登录时,传送过去的数据总是 [object Object],以至于后台识别不出来. vue 使用了 vueResource 组件,登录方法为 patch. 经过探索,终于在官网 ...
- Java 记录日志
Java9的日志级别: ALL 最低级别,系统会输出所有的日志信息,会生成大量的·.冗余的日志 TRACE 输出系统的各种跟踪信息,会生成大量的·.冗余的日志 DEBUG 输出调试信息,会生成较多的日 ...
- hibernate课程 初探单表映射1-8 hibernate持久化类
java beans 的设计原则 1 公有的类 2 共有不带参数构造方法 3 私有属性 4 属性setter/getter方法 Studnet类: package com.ddwei.student; ...
- C/S框架设计经验小结
C/S架构程序应用广泛,比如常见的QQ.微信.Outlook,还有手机上的各种APP都是C/S架构的.C指的是Client,即客户端,S指的是Server,即服务端. 经常听到初学者争论,是学C/S结 ...
- 从零开始的全栈工程师——js篇2.10(对象与构造函数)
对象与构造函数 一.js数据类型 基本数据类型:string undefined null boolean number 引用数据类型 Object array function 二 ...
- es6-异步应用
异步编程对 JavaScript 语言太重要.Javascript 语言的执行环境是“单线程”的,如果没有异步编程,根本没法用,非卡死不可.本章主要介绍 Generator 函数如何完成异步操作. 传 ...
- 【Shell脚本学习24】Shell输入输出重定向:Shell Here Document,/dev/null文件
Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示.一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器. 输出重定向 命令的输出不仅可以 ...