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 ...
随机推荐
- 设置x 轴斜体(每次我都百度,这次单独为它发一个)
plt.xticks(rotation = 45) 2020-06-07
- numpy巩固
导包 import numpy as np 创建二维数组 x = np.matrix([[1,2,3],[4,5,6]]) 创建一维数组 y = np.matrix([1,2,3,4,5,6]) x ...
- PHP fileowner() 函数
定义和用法 fileowner() 函数返回指定文件的用户 ID(所有者). 如果成功,该函数返回用户 ID.如果失败,则返回 FALSE. 语法 fileowner(filename) 参数 描述 ...
- PHP preg_replace_callback_array() 函数
preg_replace_callback_array 函数执行一个正则表达式搜索并且使用一个回调进行替换.高佣联盟 www.cgewang.com 该函数在 PHP7+ 版本支持. 语法 mixed ...
- Android中Activity启动模式探索
Android中启动模式(launchMode)分为standard, singleTop, singleTask, singleInstance四种,可通过AndroidManifest.xml文件 ...
- 埋在MySQL数据库应用中的17个关键问题!
作者:扎瓦陈序元 来源:https://blog.csdn.net/weixin_42882439 MySQL的使用非常普遍,跟MySQL有关的话题也非常多,如性能优化.高可用性.强一致性.安全.备份 ...
- BSGS 学习笔记
问题:求$a^x\equiv b\ (mod\ p)$的最小正整数解. 这时候就要用到BSGS(拔山盖世)算法.直接进入正题: 设$x=im-n$, 则原式等于$a^{im-n}\equiv b\ ( ...
- IDEA必备插件系列-Rainbow Brackets(彩虹括号)
Rainbow Brackets ,就是彩虹括号,各种鲜明颜色的括号 这个一个开源的项目: https://github.com/izhangzhihao/intellij-rainbow-brack ...
- 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!
最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...
- DIFF算法浅析(三)在react中的实现
在虚拟dom中diff的实现. 分别从4个方面: DIFF抽象概念(概述.时间复杂性分析) 在Vue2中的实现(版本2.6.11.必要性.执行方式) 在React中的实现(版本16.13.1,必要性. ...