您的位置:首页 > 数据库 > MySQL

《MySQL必知必会学习笔记》:高级联结

2016-04-03 01:47 239 查看

创建高级联结

上篇博文简单的介绍了下联结的使用,这篇博文就介绍下如何来创建高级联结。

使用表别名

在前面的学习中,我们知道如何给列取一个别名,现在回顾下,如下:

select cust_name,upper(cust_name) as upper_name from customers;




或者是,用concat函数来对客户的姓名和电话进行组合为一个新的信息 ,将这个新的信息取一个别名,如下:



以上就是给列取别名,也可以给计算字段取别名。不仅如此,SQL还允许给表名取别名。这样做有两个主要理由,如下:

缩短SQL语句

允许在单条select语句中多次使用相同的表。

下面举一个例子来说明,如何给表取别名。如下:

通过as为customers/orders/ordersitems 分别取别名为 c/o/items;这样,在后面的列引用中,直接使用别名,而不是使用全名,这样书写起来稍微可以简单一点点。



使用不同类型的联结

上篇博文中,使用过内部联结(即等值联结)。先回顾下:内部联结就是通过 table_name inner join InnerJoin_table_name on 子句来完成的;实际例子如下:



上面就是一个简单的内部联结,,由于刚好学习了给表取别名,就随带把这个知识点也加进去了。

除了内部联结之外,还有其他的3种形式,分别为:

自联结

自然联结

外部联结

下面一一进行介绍。

自联结

自联结,从字面意思就可以理解,就是只存在一个表,自己和自己联结。

下面看一个例子:想看下学生成绩表中 数学分数为100的人的英语成绩是多少分?

你可能会说,这个还需要用自联结来完成吧,直接用where过滤就应该ok了吧。

的确,对于这个例子,确实可以直接用where子句来完成,如下:



除了可以采用上面的where过滤来完成,还可以采用子查询来完成,如下:



除了采用上面介绍的两种方法之外,还可以采用 自联结来完成,如下:



这里采用自联结的方式来完成的,此查询中的表实际上时相同的表,都是student2,由于我们需要对一个表引用两次,因此就需要引入对表student2引入两个不同的别名,否则对student2的引用就存在歧义。因此MySQL不知道你引用的是student2表中的哪个实例。

当引入别名后,所有的列的访问均需要用别名来指定,否则因为有歧义而报错。

如下就是因为没有指定是student2表中的哪个实例而报错:



以上介绍了3中方法来完成这样一个操作,在实际过程中,到底该用哪一种方法,我们应该都尝试下,以确定哪一种的性能更好。

自然联结

由于对多个表进行联结的前提就是应该至少有一列出现在不止一个表中。标准的联结(即内部联结)会返回所有数据(含有重复的列)。而自然联结排除多次出现,使每个列只返回一次。

下面先看标准的联结 ,当在联结的过程中我们用(select *),则结果就是返回所有的列数据。



而自然联结是如何做到排除多次出现,使每个列只返回一次的呢??

答案是:系统不完成这项工作,由我们自己来完成它。自然联结就是这样一种联结,其中我们只能选择那些唯一的列。这一般是通过对表使用通配符(select *),对所有其他表的列使用明确的子集来完成。



简单来说:自然联结就是我们指定输出的内容,并不是输出所有的内容(因为重复的列数据不是我们想得到的)。

外部联结

明天继续,太晚了,2016年4月3日01:45:33;

今天出去耍了一天,实在是太累,看博客发现自己的这篇博文还没有完成,于是在睡觉前花了点时间,看了下外部联结,也实践了下。

如下:

上面介绍了内联结、自联结、自然联结这三种形式。下面就来介绍下外部联结。什么是外部联结呢?

MySQL必知必会这本书上面是这样说的:

许多联结将一个表中的行与另一个表中的行相关联。但有时候会需要包含没有关联行的那些行。例如:我们想看下所有客户的订单情况,包括那些至今尚未下订单的客户。

当遇到上面这种情况的时候,就需要外部联结了。

为更好的实验,我在customers表中插入了一个新的客户信息,此客户信息是没有下任何订单的。

如下:



如果我们不用外部联结,先看下内部联结的结果,看是否可以将哪些至今尚未下订单的客户显示出来,如下:



从上面的结果可以看出,内部联结是无法满足我们这个要求的(即将所有客户的订单情况显示出来,包括没有下订单的)

下面我们看下外部联结,如下:



从结果可以看出,外部联结将所有客户的订单情况进行了显示,包括那些没有下订单的客户。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。 这也是外部联结和内部联结的一个重要的不同的地方。

不知道到这里,大家是否都理解了外部联结。

简单来说就是联结包含了那些在相关表中没有关联行的行,这种类型的联结就是外部联结。

下面就将外部联结的语法讲解一下。

外部联结包括:左外部联结(left outer join)和右外部联结(right outer join)。

左外部联结就是:left 指出的是outer join左边的表,即使用left outer join 从from子句的左边表(上例中的customers表)中选择所有行。

为了从右边的表中选择所有行,应该使用right outer join



除了使用上面的right outer join 方式外,我们还可以在left outer join 方式的基础上直接将两个表的位置进行交换,也是可以达到同样的效果。即左外部联结可通过颠倒from或where子句中表的顺序转换为右外部联结。

总结

关于联结的使用,总结如下:

1)注意所使用的联结类型,一般我们使用的是内部联结,但外部联结也是有效的。

2)保证使用正确的联结条件,否则返回不正确的结果

3)应该总是提供联结条件,否则会得到笛卡尔积。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: