SQL联结笔记(内联结,自联结,自然联结,外联结区别以及应用)
SQL中有三种联结,分别是:内联结,自然联结,外联结.
联结是针对不同表联合起来的一种方式.应用的对象是:表(table)
为了方便验证练习理解,首先展示所要用到的表的内容:
1.Customers表:
数据(可复制,创建表,插入数据):
CREATE TABLE Customers
(
cust_id char(10) NOT NULL ,
cust_name char(50) NOT NULL ,
cust_address char(50) NULL ,
cust_city char(50) NULL ,
cust_state char(5) NULL ,
cust_zip char(10) NULL ,
cust_country char(50) NULL ,
cust_contact char(50) NULL ,
cust_email char(255) NULL
);
-- ------------------------
-- Populate Customers table
-- ------------------------
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state,
cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000001', 'Village Toys', '200 Maple Lane', 'Detroit', 'MI',
'44444', 'USA', 'John Smith', 'sales@villagetoys.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state,
cust_zip, cust_country, cust_contact)
VALUES('1000000002', 'Kids Place', '333 South Lake Drive', 'Columbus', 'OH',
'43333', 'USA', 'Michelle Green');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state,
cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000003', 'Fun4All', '1 Sunny Place', 'Muncie', 'IN', '42222',
'USA', 'Jim Jones', 'jjones@fun4all.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state,
cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000004', 'Fun4All', '829 Riverside Drive', 'Phoenix', 'AZ',
'88888', 'USA', 'Denise L. Stephens', 'dstephens@fun4all.com');
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state,
cust_zip, cust_country, cust_contact)
VALUES('1000000005', 'The Toy Store', '4545 53rd Street', 'Chicago', 'IL',
'54545', 'USA', 'Kim Howard');
-- ----------------------
展示:
2.Vendors:
-- -------------------
-- Create Orders table
-- -------------------
CREATE TABLE Orders
(
order_num int NOT NULL ,
order_date datetime NOT NULL ,
cust_id char(10) NOT NULL
);
-- ----------------------
-- Populate Vendors table
-- ----------------------
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state,
vend_zip, vend_country)
VALUES('BRS01','Bears R Us','123 Main Street','Bear Town','MI','44444', 'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state,
vend_zip, vend_country)
VALUES('BRE02','Bear Emporium','500 Park Street','Anytown','OH','44333',
'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state,
vend_zip, vend_country)
VALUES('DLL01','Doll House Inc.','555 High Street','Dollsville','CA','99999',
'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state,
vend_zip, vend_country)
VALUES('FRB01','Furball Inc.','1000 5th Avenue','New York','NY','11111',
'USA');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state,
vend_zip, vend_country)
VALUES('FNG01','Fun and Games','42 Galaxy Road','London', NULL,'N16 6PS',
'England');
INSERT INTO Vendors(vend_id, vend_name, vend_address, vend_city, vend_state,
vend_zip, vend_country)
VALUES('JTS01','Jouets et ours','1 Rue Amusement','Paris', NULL,'45678',
'France');
-- -----------------------
3.Products:
-- ---------------------
-- Create Products table
-- ---------------------
CREATE TABLE Products
(
prod_id char(10) NOT
NULL ,
vend_id char(10) NOT
NULL ,
prod_name char(255) NOT NULL ,
prod_price decimal(8,2) NOT NULL ,
prod_desc
text NULL
);
-- -----------------------
-- Populate Products table
-- -----------------------
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR01', 'BRS01', '8 inch teddy bear', 5.99, '8 inch teddy bear, comes
with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR02', 'BRS01', '12 inch teddy bear', 8.99, '12 inch teddy bear, comes
with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BR03', 'BRS01', '18 inch teddy bear', 11.99, '18 inch teddy bear, comes
with cap and jacket');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG01', 'DLL01', 'Fish bean bag toy', 3.49, 'Fish bean bag toy,
complete with bean bag worms with which to feed it');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG02', 'DLL01', 'Bird bean bag toy', 3.49, 'Bird bean bag toy, eggs
are not included');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('BNBG03', 'DLL01', 'Rabbit bean bag toy', 3.49, 'Rabbit bean bag toy,
comes with bean bag carrots');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RGAN01', 'DLL01', 'Raggedy Ann', 4.99, '18 inch Raggedy Ann doll');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RYL01', 'FNG01', 'King doll', 9.49, '12 inch king doll with royal
garments and crown');
INSERT INTO Products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('RYL02', 'FNG01', 'Queen doll', 9.49, '12 inch queen doll with royal
garments and crown');
4.Orders
-- -------------------
-- Create Orders table
-- -------------------
CREATE TABLE Orders
(
order_num int NOT NULL ,
order_date datetime NOT NULL ,
cust_id char(10) NOT NULL
);
-- ---------------------
-- Populate Orders table
-- ---------------------
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20005, '2012-05-01', '1000000001');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20006, '2012-01-12', '1000000003');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20007, '2012-01-30', '1000000004');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20008, '2012-02-03', '1000000005');
INSERT INTO Orders(order_num, order_date, cust_id)
VALUES(20009, '2012-02-08', '1000000001');
好吧,如上原始数据已经有了,现在我们来理解SQL几种联结之间的关系和细节.
1.为什么要使用联结:
有时候为了方便存储,我们会把数据分解为多个表.例如,现在某公司需要用到以下产品,别人对应的供应商和价格如下:
这一张表存了供应商的信息和产品以及价格.可以看到这个供应商给我们提供了两种产品:QQ和邮箱;
这两种产品都是出自于同一个供应商,因此我们存储数据的时候,"供应商的地址"和"联系人" 就被重复存储了".现实应用中,一个供应商可能提供的产品远远超过2个,
这就会给我录入数据和存储数据和更新数据带来很大的麻烦.譬如:这个提供多种产品的供应商的地址需要更新的时候
于是我们可以把张表分解成两个表,关联两个表主键(方便查询,也就是相关联的共同的信息),如下:
1.
2.
这样一来,后续要我更新某个供应商的地址和联系人的时候,只需要对表2中的对应内容进行更新就好了.这样分解表后的两个表更直观一些了,但是在我们处理查询数据的时候,就要关联两个表中的
信息了,操作的复杂度就增大了.按照我们常规的处理方式,
如果我们要查提供某一个产品的供应商的全部信息,那就要先到表2中把供应商的地址和联系人先查出来,然后再结合表1中对应产品的其他信息
这时我们一种方式是分步处理:
1,按照步骤来,首先在表1中查出对应产品的供应商
2.在表2中查出对应的供应商的地址和联系人信息
另外一种是,嵌套子查询,一步设置完查询
但是这两种方式,操作起来都不是太方便,在输入的时候可能要多输入一些条件和内容才能达到我们想要的结果.因此就有了联结的概念.
如最上面所说,联结有几种方式:内联结,自联结,自然联结,外联结
内联结(INNER JOIN):内联结也可以称为等值联结.例如:
如以上两个表格中,每个订单包含订单编号,客户ID,订单日期,在Orders表中存储为一行,各订单的物品存储在相关的OrdersItems表中.Orders表不存储顾客的信息,只存储顾客ID.顾客的实际信息存储在Customers
表中.
现在,假如需要列出订购物品"RGAN01"的所有顾客,应该怎样检索?
步骤为下:
1.检索包含物品RGAN01的所有订单的编号.
2.检索具有前一步骤列出的订单编号的所有顾客 的ID
3.检索前一步骤返回的所有顾客ID的顾客信息
方法一:以上每步可以单独作为一个查询来执行.可以把一个SELECT 语句返回的结果用于另外一条SELECT语句的WHERE子句.
方法二:也可以使用子查询把3个查询组合成一条语句
方法三:直接使用内联结来关联两个表直接查询.
方法一实现:
2.方法二实现:
3.方法三实现:
上面是通过 WHERE 语句来实现的,这里面等同于 INNER JOIN...ON (INNER JOIN基本上只用于联结两个表,不太适合多个表联结).
INNER JOIN ...ON 的使用方式
2.自联结
例如:现在要给Jim Jones同一公司的所有顾客发送一封信件.这个查询要求首先找出Jim Jones工作的公司,然后找出在该公司工作的顾客.下面是实现代码:
通过customers表可以看出,cust_contact 里面对应的 Jim Jones 的公司是,Fun4All,然后筛选出 Fun4All 公司的其他联系人和客户ID
以上是通过子查询的方式实现的.
先对对比一下自联结方式实现:
此处要非常小心一定是要c2来进行过滤
3.自然联结
无论何时对表进行联结,应该至少有一列不止出现在一个表中(被联结的列).标准的联结(前一课中介绍的内联结)返回所有数据,相同的列甚至多次出现.
自然联结排除多线出现,使每列只返回一次.
自然联结要求只能选择那些唯一的列,一般通过对一个表使用通配符(SELECT*),而对其他表的列使用明确的子集来完成.如:
在这个例子中,通配符只对第一个表使用,所有其他列明确列出,所以没有重复的列被检索出来.事实上,我们目前所学的每个内联结都是自然联结
4.外联结
许多联结将一个表中的行与另一个表中的行相关联,但有时候需要包含没有关联行的那些行.
例如:
A.对每个顾客下的订单进行计数,包括那些至今尚未下订单的顾客;
B.列出所有产品以及订购数量,包括没有人订购的产品
C.计算平均销售规模,包括那些至今尚未下订单的顾客.
这种联结包含了那些在相关表中没有关联行的行的联结方式就是外联结
例如:
外联结使用的时候,注意区分 LEFT OUTER JOIN 还是 RIGHT OUTER JOIN 就是设定展示哪边的表的所有行.另外还可以使用FULL OUTER JOIN
SQL联结笔记(内联结,自联结,自然联结,外联结区别以及应用)的更多相关文章
- SQL server 使用 内联结(INNER JOIN) 联结多个表 (以及过滤条件 WHERE, AND使用区别)
INNER JOIN ……ON的语法格式: FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INN ...
- SQL学习之高级联结(自联结、自然联结、外联接)
create table Customers( Id ,), Company ) null, Name ) null ) insert into Customers values('Fun4All', ...
- SQL 必知必会·笔记<11>创建高级联结
1. 使用表别名 SQL 除了可以对列名和计算字段使用别名,还允许给表名起别名.这样 做有两个主要理由: 缩短SQL 语句: 允许在一条SELECT 语句中多次使用相同的表. 使用表别名示例: SEL ...
- SQL学习笔记
SQL(Structured Query Language)学习笔记 [TOC] Terminal登录数据库 1.登录mysql -u root -p ; 2.显示所有数据库show database ...
- 1.4(SQL学习笔记)分组、子查询、联结、组合查询
一.分组 建表及数据填充语句下载:链接: https://pan.baidu.com/s/1WHYafwqKJEKq1kDwCH_Zlg 提取码: 3wy4 1.1初识分组 分组是按照某一列,将该列中 ...
- ORALCE PL/SQL学习笔记
ORALCE PL/SQL学习笔记 详情见自己电脑的备份数据资料
- 你真的会玩SQL吗?EXISTS和IN之间的区别
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- SQL Server中Text和varchar(max)数据类型区别
SQL Server中Text和varchar(max)数据类型区别 以前只知道text和image是可能被SQL Server淘汰的数据类型,但具体原因不太清楚,今天读书的时候发现了text与v ...
- SQL Server排序函数row_number和rank的区别
SQL Server排序函数row_number和rank的区别 直接看测试结果 declare @table table(name varchar(100),amount int, memo var ...
随机推荐
- 关闭,centos yum的自动更新
今天我虚拟机提示我满了,,,打开磁盘分析器一看,yum的更新目录满了,本地虚拟跟生产环境的版本完全一致,所以我也不打算更新,找一下命令,得先安装yum-cron ,然后再禁止更新 [root@loca ...
- IDEA解决MAVEN下载插件慢问题
原文链接:https://blog.csdn.net/qq_25983579/article/details/104398915 使用阿里的maven镜像 右键项目选中maven选项,然后选择“ope ...
- Python爆火的原因与未来|内附Python学习书籍大礼包无偿领取|
从12年到20年,python以肉眼可见的趋势超过了java,成为了当今It界人人皆知的编程语言. python为什么这么火? 网络编程语言搜索指数 适合初学者 Python具有语法简单.语句清晰的特 ...
- Python访问、修改、删除字典中的值
Python访问字典中的值: # 使用字典 ['键'] 获取字典中的元素 dic = {'a':123,'b':456,'c':789} print(dic['a']) # print(dic['c' ...
- Django学习路15_创建一个订单信息,并查询2020年\9月的信息都有哪些
在 app5.models.py 中添加一个 Order 表 class Order(models.Model): o_num = models.CharField(max_length= 16 ,u ...
- 解决痛苦的方法/cy
这篇文章 源于我所有痛苦的回忆. 由于痛苦太多了 体会完了 所以 觉得这些都不算是什么大问题了 所以 这里 是解决痛苦的方法. 真的很痛苦的话 可以这样 对着全班人喊你们 都没我强 因为 你们都没有我 ...
- 这届 Showgirl行不行?AI告诉你谁是ChinaJoy上最漂亮的小姐姐
摘要: CJ开幕,顶着三伏天的酷暑高温,暴走一整天,就为了拍点漂亮小姐姐给大家看看. 一年一度的游戏视觉盛宴又来了! 作为一个游戏动漫控的肥宅,去CJ现场是必须的.除了看看游戏和动漫,各大游戏展台漂亮 ...
- RabbitMQ学习总结(3)-集成SpringBoot
1. pom.xml引用依赖 SpringBoot版本可以自由选择,我使用的是2.1.6.RELEASE,使用starter-web是因为要使用Spring的相关注解,所以要同时加上. <dep ...
- WPF桌面程序在请求接口时如何防止被常用的抓包软件Fiddler抓包
问题:在我开发了一个WPF桌面应用程序的时候,由于涉及到登录等等操作通过Fiddler可以很直观的看到账号密码.首先问题有两点:1.数据提交的时候对于密码等重要的数据没有进行加密操作.2.没有防止抓包 ...
- github开源文章生成pdf
最近需要研究ELK,然后在网上发现了有本书写的不错,然后搜到是在 github 上开源过的.这本书的时间有点久了,就想通过源码自己来生成一个 pdf 我使用的是 ubuntu 系统 step1:安装 ...