《[原创]多表连接(join)小结》由会员分享,可在线阅读,更多相关《[原创]多表连接(join)小结(4页珍藏版)》请在金锄头文库上搜索。
1、原创 多表连接 (join)小结参考:sql 查询初学者指南第二版,机械工业出版社基础内链接就是对表 A 和表 B 以元组为单位做一个笛卡尔积,记为表 C,然后在 C 中挑选出满足符合 on 语句后边的限制条件的条目。左连接就是在内连接的基础上,将 A 中有但 C 中没有的元组也加上。由于 C 的列数比 A 的列数多,所以这新增的元组左边照搬 a,右边为 null。右链接就是在内连接的基础上,将 B 中有但 C 中没有的元组也加上。由于 C 的列数比 B 的列数多,所以这新增的元组右边照搬 B,左边为 null。所谓的 full join ,就是在 join 的结果 d 后边先加上 left
2、join 要加的项,再加上 right join 要加的项所谓的交叉连接(select * from tableName1 cross join tableName2)和 select * from tableName1, tableName2 是一样的,都是得到笛卡尔积。可以用 select * from table1,table2 where.模拟 join 操作。所谓的自身连接是指同一个表自己与自己进行连接。这种一元连接通常用于从自反关系(也称作递归关系)中抽取数据。例如人力资源数据库中雇员与老板的关系。直接写 join 就是内连接,相当于 inner join, inner 可省写 l
3、eft join 或者 right join 就是外连接,outer 可省例子有两表 A 和 BAB下面是一些 select 操作select * from A cross join Aselect * from A join B on A.name = B.name就是对笛卡尔积,也即上边的 cross join 的结果进行进一步筛选,选出满足A.name=B.name 的行。只有两行符合条件在上衣 select 语句的基础上增加了一行select * from A left join B on A.name = B.name同上select * from A right join B on
4、 A.name = B.nameselect * from A full join B on A.name = B.name进阶重要理论依据:在可以指定一个表名的任何地方,都可以指定一个括号括起来的 join 子句。在两个表的一个完整 join 语句出现的任何一个地方,我们都可以只用一个表名来代替它。所谓“两个表的一个完整 join 语句” 也即“join 子句”,就是指如“A join B on A.a= B.b”这样一个完整的句子比如:欲连接 ABCDE 五个表可以这样:Select * from A inner join(B inner join C on B.b = C.c)inner
5、 join D on B.b = D.d)inner join E on D.d = E.e)on A.a = E.e也可以这样:select * from (A inner join B on A.a = B.b)inner join C on C.c = A.a)inner join D on D.d = C.c)inner join Eon E.e = D.d也可以这样:select * fromA inner join B on A.a = B.binner join C on C.c = A.ainner join D on D.d = C.cinner join E on E.e
6、= D.d我们可以先把 A 和 B 连接起来,然后将结果与 C 连接,当然,如果 C 只和 B 相关而不和 A 相关的话,我们也可以先把 B 和 C 连接起来,结果再与 A 连接,只要保持关系是正确的,你可以以任意方式来定义嵌套的 join。然而大多数数据库系统会分析整个 from 子句,然后尝试确定组合连接表的最有效方式,也就是说数据库不不一定会从最里边的括号开始执行查询。这很可能打乱你的逻辑设计,得到意外的结果。另外,一些数据库系统中的优化器对于 join 定义的顺序很敏感。如果你发现使用很多 join 的查询在一个较大的数据库上执行花很长时间,通过改变 sql 语句中的 join 顺序很
7、可能能够使它运行的更快。注意:有时候,你只需要 A 和 C 表中的一部分数据,但 A 和 C 只有通过 B 才能发生关系,那么你依然要先将 A 和 B 连接,然后再连接 C一个比较全面的例子:select RCFiltered.ClassName, R.RecipeTitlefrom(select RecipeClassId,RecipeClassDescription as ClassNameFrom Recipe_Classes as RCwhere RC.ClassName = Salads or RC.ClassName = Soup or Rc.ClassName = Main Co
8、urse)as RCFilteredleft outer join Recipes as Ron RCFiltered.RecipeClassId = R.RecipeClassId这个例子的内涵:1. 在大多数 sql 的实现中,我们可以把 from 子句中的任何表名替换成一条完整的 select 语句. 当然,必须分配一个相关名称。本例中为子 select 语句分配的名称为 RCFiltered,在第 7行。2. 当我们决定以 select 代替表名的时候,要确保 select 的结果不仅包含想要出现在最终结果中的列,而且包含需要执行 join 的列。这就是为什么我们在嵌入的 select 语句中既看到了RecipeClassId 又看到了 RecipeClassDescription.3. 我们给 RecipeClassDescription 一个别名 ClassName,所以在第一行使用了RDFiltered 的别名。第一行的 select 只看到了表 RCFiltered,看不到表 Recipe_Classes