为什么要使用联结?
我们在设计数据库表的时候,往往会把数据分解为多个表,能够够有效的存储。但是,如果数据存储在多个表,怎么用单条select语句检索出数据呢?这是我们就可以使用联结。
一、创建联结
创建联结非常简单,只需要规定要联结的所有表以及它们如何关联即可。
示例:
select vend_name, prod_name, prod_price
from vendors, products
where vendors.vend_id = products.vend_id;
注意:在引用的列可能出现二义性时,必须使用完整的全限定列名(用一个句点分隔的表名和列名)。
二、笛卡尔积:
由没有联结条件的表关系返回的结果为笛卡尔积。检索出的行数将是第一个表中的行数乘于第二个表的行数。
所以,应该保证所有的联结都有where子句,否则DBMS将返回比想要的数据多得多的数据。
三、联结分类
1、内部联结
内部联结也加等值联结,它基于两个表之间的相等测试。
上面的示例也可以如下使用 INNER JOIN 表示,效果完全一样:
select vend_name, prod_name, prod_price
from Vendors INNER JOIN Products
ON vendors.vend_id = products.vend_id;
2、自联结
自联结是在同个表的联结,有时候我们会使用子查询来查询信息:
select from_date, thru_date
from official_history
where history_id =
(select history_id
from official_history
where content_id = '13145test')
但是经常使用子查询对性能影响很大,所以我们可以使用自联结查询:
select c1.from_date, c1.thru_date
from official_history as c1, official_history c2
where c1.history_id = c2.history_id
and c2.content_id = '13145test'
将official-history表命名两个不同的别名,利用两个别名配合来实现查询
3、自然联结
自然联结排除多次出现,使每个列只返回一次,而且必须由我们自己完成这项任务,选择那些唯一的列。
select o.*, c.content_data
from official_history as o, content as c
where o.content_id = c.content_id
and o.is_delete = 0
在上面的例子,我们手动设置查询offcial_history表的所有字段,且只查询content表的content_data字段
4、外部联结
许多联结将一个表中的行与另一个表中的行相关联,但有时候会需要包含没有关联行的那些行。
比如下面的示例中,只会查询到符合content.content_id = official_history.content_id条件的记录,不如两个表中有一个表没有对应的id,则不会匹配:
select official_history.content_id , history_id, content_data
from official_history, content
where content.content_id = official_history.content_id
但是我们有时候会需要查询一个表的所有行,不管联结的表中是否有对应的行相关联,这是我们就可以使用外部联结,示例:
select history_id, official_history.content_id ,content_data
from official_history left outer join content
on content.content_id = official_history.content_id
这条select语句使了OUTER JOIN来指定联结的类型,在使用时必须使用RIGHT或LEFT关键字指定包括其所有行的表(RIGHT值指的是OUTER JOIN右边的表,LEFT是指其左边的表)。
使用联结时的性能考虑:
DBMS在运行时关联指定的每个表以处理联结,这种处理可能是非常耗费资源的,因此应该仔细考虑,不要联结不必要的表。联结的表越多,性能下降地越厉害。