SQL Server第六章-多表连接查询

第1关:带 WHERE 子句的多表查询
任务描述
本关任务:使用带 WHERE 子句的多表查询方法,检索数据表中的指定内容。
相关知识
为了完成本关任务,你需要掌握:如何使用带 WHERE 子句的方法查询多表数据。
理解连接
SQL 最强大的功能之一,就是能使用数据检索语句来连接多张数据表。 连接 (Join) 是使用数据库时最重要的操作,所以理解什么情况下,能连接和如何连接是学习 SQL 中极其重要的部分。
在你使用连接查询之前,一定要搞清楚数据表之间的关系。那怎么理解数据表之间是有关系的呢?
举个例子
假设现在你有一张商品的列表,这张列表里包含了每个商品的名称、信息以及价格。现在的问题是,如果这些产品有一部分来自相同的生产厂家,你打算在哪里存储这些厂家的信息(比如厂家地址、信息及联系方式)?
有两种选择,一种是把厂家的信息和产品信息存储在一张数据表里,另一种是建立新的数据表来存储厂家的信息。
不知道你会选哪一种存储方式?
我们推荐选第二种,因为:
有很多商品来自同一厂家,在存储的时候,就势必会造成大量的重复信息涌入商品数据表,这样既浪费时间,又浪费空间;
如果厂家更换了信息(比如地址或者电话),你将要更新每一个出现在商品数据表中的厂家信息,这太费劲儿了!
当信息内容大量重复时,你没有办法保证写入的每一条信息都和其他的一模一样,很有可能会在字符上有些许差异,数据不一致将来很难进行操作。
Tips:
一张数据表里出现多条相同的数据并不是一件好事,这个原则也同样适用于关系数据库的设计。我们推荐把不同种类的信息放在不同的数据表中,但是有关系的两张表,可以被同一种数据所关联。
用WHERE子句创造一个连接
两张数据表是如何被关联起来的呢?
你只需要列出所有被关联到的表,并写出他们是怎样的关系就可以了。抽象吗?
举个例子
我们现在有两张数据表,student 表中存储了学生信息,class 表中存储了班级信息。但是很显然,student 数据表里并没有存储学生的班级,而是学生班级的 id。我们只有将两张表关联起来,才能查询到学生所属的班级,但是,如何将两张数据表关联起来呢?
在这里插入图片描述
在这里插入图片描述
输入:
SELECT *
FROM student, class
WHERE student.class_id = class.class_id
该例中,我们在 WHERE 关键字后使用student.class_id = class.class_id 语句用来关联这两张表。我们可以理解为,当 student 表与 class 表中的 class_id 字段内容相同时,我们可以将两张表中 class_id 字段对应的内容行拼接成一张表。
输出:
在这里插入图片描述
注意到,class 表中的 class_id = 308 的内容行,并没有出现在我们的关联后的新表中。因为 student 表中的 class_id 并没有出现过内容 308 。现在我们可以大大方方的说,我们关联后的表是取了表 student 和表 class 的交集,如下图所示:
在这里插入图片描述
检索过程:
在这里插入图片描述
有的同学可能会注意到,这里出现了重复的显示项 class_id ,我们将在下一关里介绍如何去掉它。
编程要求
我们已经为你建好了数据库与数据表,并添加了相应的数据内容。你只需在右侧 Begin-End 区域内补充代码,用 WHERE 子句关联表 Products 和表 Vendors 。
表 Products 和表 Vendors 的内容如下图所示:
在这里插入图片描述
在这里插入图片描述
测试说明
测试过程:
本关涉及到的测试文件是 step1_test.sh ,平台将运行用户补全的 step1.sql 文件,得到数据;
将得到的数据与答案比较,判断代码是否正确。
如果操作正确,你将得到如下的结果:
在这里插入图片描述
参考代码:

USE Mall
GO
SET NOCOUNT ON
--********** Begin **********--
SELECT * 
FROM Products, Vendors
WHERE Products.vend_id = Vendors.vend_id
--********** End **********--
GO

第2关:内连接查询
任务描述
本关任务:使用自然连接多表查询方法,检索数据表中的指定内容。
相关知识
为了完成本关任务,你需要掌握:
如何使用等值查询的方法查询多表数据;
如何使用自然查询的方法查询多表数据。
我们之前学到的 WHERE 连接也称为等同连接,这种类型的连接我们一般称它为内连接(Inner Joins),包含关系如下图所示:
在这里插入图片描述
事实上,我们可以使用另一种专门的语法,来表示这种类型的连接。以后你将会学到其他类似的语法,来表示其他类型的连接。
等值连接
等值连接使用 = 来进行比较运算。
举个例子
还记得上一关我们用到的例子吗?在上一关中,为了查询每个学生所对应的班级,我们用 WHERE 语句将表 student 和表 class 关联了起来。
在这里插入图片描述
在这里插入图片描述
代码如下:
SELECT *
FROM student, class
WHERE student.class_id = class.class_id
现在,我们用内连接查询语法进行查询,你将看见,它返回的结果与上一关一模一样。
输入:
SELECT *
FROM student inner join class
ON student.class_id = class.class_id
在该语法中,我们将两张需要关联的表放在了 join 的两端,并用 ON 代替之前的 WHERE 关键字。
输出:
在这里插入图片描述
检索过程:
在这里插入图片描述
结论:
若要连接表 t1 和表 t2 ,比较条件为 t1.a = t2.a,那么数据库会用 t1 中 a 列的所有元素逐个和 t2 中的 a 列进行比较,如果相等,则输出该行。
不等值连接
在内连接中,如果不使用 = 作为比较运算符,我们就叫它不等值连接。
举个例子
在查询每个学生所对应班级的这个例子中,若使用不等值连接,将会返回: student 表和 class 表中, class_id 字段不相等的所有组合。
输入:
SELECT *
FROM student inner join class
ON student.class_id <> class.class_id
输出:
在这里插入图片描述
检索过程:
在这里插入图片描述
结论:
若要连接表 t1 和 t2 ,比较条件为 t1.a <> t2.a,那么数据库会用 t1 中 a 列的所有元素逐个和 t2 中的 a 列进行比较,如果不相等,则输出该行。
自然连接
自然连接是一种特殊的等值连接,但与等值连接及其类似。大家可能已经注意到,我们之前的连接查询结果,都会出现两列重复的 class_id ,但在自然连接查询结果中,我们将只能看见一列 class_id。
怎么做到的呢?自然连接,相当于在等值连接的基础上,加了显示的限定条件,从而实现了列去重。
它还和等值查询有一个明显的区别:
自然连接要求比较的两个列属性必须相同,等值连接则不需要。
举个例子
查询每个学生所对应的班级:
输入:
SELECT student.*, class.class_name
FROM student inner join class
ON student.class_id = class.class_id
输出:
在这里插入图片描述
检索过程:
在这里插入图片描述
编程要求
我们已经为你建好了数据库与数据表,并添加了相应的数据内容。你只需在右侧 Begin-End 区域内补充代码,用自然连接关联表 Products 和表 Vendors 。
表 Products 和表 Vendors 的内容如下图所示:
在这里插入图片描述
在这里插入图片描述
测试说明
本关涉及到的测试文件是 step2_test.sh ,平台将运行用户补全的 step2.sql 文件,得到数据;
将得到的数据与答案比较,判断代码是否正确。
如果操作正确,你将得到如下的结果:
在这里插入图片描述
参考代码:

USE Mall
GO
SET NOCOUNT ON
--********** Begin **********--
SELECT Products.*,Vendors.vend_name,Vendors.vend_phone
FROM Products inner join Vendors
ON Products.vend_id = Vendors.vend_id
--********** End **********--
GO

第3关:外连接查询
任务描述
本关任务:使用左连接和右连接多表查询方法,检索数据表中的指定内容。
相关知识
为了完成本关任务,你需要掌握:
如何使用左连接查询的方法查询多表数据;
如何使用右连接查询的方法查询多表数据。
有的时候,我们不仅想知道在两张表中,什么内容是可以匹配查询到的。还想知道那些没有被关联到的内容是什么?比如在百货公司里,我们不仅想知道哪些商品被顾客买走了,还想知道那些没有买走的东西是什么,以调整将来的供货策略。
左连接
左连接以左表为基础,显示左表中的所有记录:
显示的记录条数 = 左表中记录的条数
再用左表中的指定列,来和右表中的指定列比较。满足,则输出值;不满足,则输出 NULL。
举个例子
如果你有两张表,分别为表 student 和表 class ,要查出每个学生所对应的班级名称,用左连接应该怎么做?
在这里插入图片描述
在这里插入图片描述
输入:
SELECT *
FROM student left join class
ON student.class_id = class.class_id
输出:
在这里插入图片描述
在这里,左表的第 4 条记录并没有匹配到右表的任何内容,所以右表的相应内容显示为 NULL 。
检索过程:
在这里插入图片描述
右连接
右连接与左连接正好相反,右连接以右表为基础,显示右表中的所有记录:
显示的记录条数 = 右表中记录的条数
再用右表中的指定列,来和左表中的指定列比较。满足,则输出值;不满足,则输出 NULL。
举个例子
如果你想连接表 student 和表 class 查询每个学生所对应的班级名称,用右连接应该怎么做?会与左连接查询有多大的区别呢?
在这里插入图片描述
在这里插入图片描述
输入:
SELECT *
FROM student right join class
ON student.class_id = class.class_id
输出:
在这里插入图片描述
在这里,右表的第 4 条记录并没有匹配到左表的任何内容,所以左表的相应内容显示为 NULL 。
检索过程:
在这里插入图片描述
全连接
全连接类似于左连接和右连接的综合:
显示记录的条数 = 指定比较字段在两个表中的不同种类数
对于空余字段,则显示 NULL 。也就是说,它能返回两个表中所有的关联信息,以及所有没有被关联到的信息。
举个例子
我们现在用全连接查询方法,连接表 student 和表 class,查询每个学生所对应的班级名称:
在这里插入图片描述
在这里插入图片描述
输入:
SELECT *
FROM student full join class
ON student.class_id = class.class_id
输出:
在这里插入图片描述
检索过程:
在这里插入图片描述
编程要求
我们已经为你建好了数据库与数据表,并添加了相应的数据内容。你只需根据提示,在右侧 Begin-End 区域内补充代码,分别用左连接和右连接关联表 Products 和表 Vendors。
表 Products 和表 Vendors 的内容如下图所示:
在这里插入图片描述
在这里插入图片描述
测试说明
本关涉及到的测试文件是 step3_test.sh,平台将运行用户补全的 step3.sql 文件,得到数据;
将得到的数据与答案比较,判断代码是否正确。
如果操作正确,你将得到如下的结果:
在这里插入图片描述
参考代码:

USE Mall
GO
SET NOCOUNT ON
--********** 左连接 **********--
--********** Begin **********--
SELECT *
FROM Products left join Vendors
ON Products.vend_id = Vendors.vend_id
--********** End **********--
--********** 右连接 **********--
--********** Begin **********--
SELECT *
FROM Products right join Vendors
ON Products.vend_id = Vendors.vend_id
--********** End **********--
GO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值