浅析表连接

表连接

表连接是一个很有意思的事情,报表中常用的就是JOIN和LEFT JOIN,可能大家也会看到INNER JOIN , LEFT OUTER JOIN等,它们的关系,请读者自己网上查阅,在这里我们要卖个关子。

对初学者来说,表连接是很容易迷糊的一点。容易混淆的原因是因为进行表连接时,经常会把关联字段和关联字段中存的数据混在一起说,容易给人误解。 还是第2节中的例子,我们知道,《人员主集》.’国籍’和《代码项》.’代码项内码’的数据是有关联的,一般在我们的系统中,‘国籍’中的数据,在’代码项内码’中都能找得到。

当我们说,可以通过这两个字段,将这两个表连接起来,其实真正意思是可以通过这两个字段中的数据把这两个表连接起来,请务必牢记这一点,真正在关联中起作用的是字段中的数据,是表中的那实实在在的若干条记录决定了查找出来的结果集。

说到连接,如果每张表都只有一条记录,那我们头脑中想象出来的表连接结果就很直观,我们很容易就能感受到,只需要把两表中各自的一条记录,像编一条绳子一样串起来就行了,串起来用到的’扣’就是两个连接字段中相等的数据。如下图:

内连接

用JOIN关键字进行连接就叫内连接。

JOIN…ON…部分做的事情就是用’国籍’字段和’代码项内码’字段对两表进行内连接,连接的结果是保留了两个表总共的5个字段,注意,表连接并不会合并字段,也不会增加新字段,会保持两个表的原有字段不动,我们可以把表连接的结果,看成是如下的一张虚拟中间表:

数据库执行SQL的顺序是从FROM开始, 然后是JOIN部分,最后再是SELECT部分, 我们阅读的顺序一般也是如此 。

如果我们的数据是如下的情况,结果又会如何呢?

如上图,《人员主集》中只有张三1条记录,《代码项》中也只有美国1条记录,而张三的’国籍’字段跟美国的’内码’字段不匹配,所以还是上一段SQL,我们的结果集就会是空,什么记录都拿不到,因为表连接之后产生的虚拟中间表是没有记录的。虚拟中间表内的数据,如下图。

由于关联字段串联不起来,导致我们的虚拟中间表里没有数据,从而逻辑顺序排在后面的SELECT部分,拿不到任何数据。

在进行SELECT的时候,同样的一段SQL, 同样的连接字段,会因为表中的数据不同,尤其是连接字段中数据的不同,产生不同的结果集。所用连接字段的数据严重影响了我们的结果集, 我们写的SQL语句,可以理解为,是用字段来代指一列数据,而实际影响结果集的是表中存在的记录,我们在制作报表的过程中,很大一部分的工作,是在反复’侦查’特殊数据对结果集的影响,要做到报表的数据准确,我们必须掌握数据的’侦查’能力。

上面展示了用JOIN进行表连接, 一条记录的情况,如果记录多一点会怎样,还是用主子集的表结构举例:

就像连接线中描述的那样,我们最终会得到5条记录,如下图:

如果两个表的记录改成如下所示:

那JOIN的结果会是:

产生的虚拟中间表中没有李四的记录了,在这里读者可以对JOIN的结果有一个直观的感受,使用JOIN时,我们把两个表看做两个仓库:仓库A和仓库B,把表连接产生的虚拟中间表看成仓库C。把两个原始表中的记录,看做仓库中存放的很多条绳子,所以现在,仓库A和仓库B都存放了若干条绳子,仓库C暂时是空的。

我们把SQL语句中规定的关联字段看做系绳子时用于打结的部分,在使用JOIN进行表连接的时候,两个仓库的绳子要想系起来, 仓库管理员会遍历查找仓库A和仓库B的每一条绳子,我们可以简单的认为,它是按如下的方式遍历的:

不妨给仓库A、B中的每一条绳子编下号1、2、3、N…… 仓库管理员会先复制一份A.1,我们就叫它A.1C吧, 然后带着A.1C,去和仓库B中的绳子挨个比对,当发现仓库B中的某条绳子B.N的关联字段的值和A.1的关联字段的值相等时,就复制一条B.N,产生一条新绳子叫B.NC,然后系一下A.1C和B.NC,放到仓库C里去,这算一个来回,仓库管理员还得再回仓库A,继续复制出一条A.1C,带去仓库B作比较,这次,他只需要从B.N+1继续比对就可以了,发现相等的,就再系下放到仓库C 。这样来来回回,如果仓库B中有多条绳子跟A.1匹配的,那么最终仓库C中,就会出现多条绳子的前半段都是A.1的情况,比如上图的虚拟中间表,张三的记录,就出现在仓库C中绳子的左半端,出现了3次。因为张三那条记录的连接字段:’国籍’,在仓库B中匹配成功了三次,匹配成功一次,就放到仓库C中一次。

如果张三这条记录是相亲节目的男嘉宾,他是不是很嗨皮, 如果对于某条绳子A.N,仓库B中从头到尾没有匹配的,那A.N这根绳子,是注定不会出现在仓库C中了,再回头看下上两图的原表和虚拟中间表,《人员主集》中李四这条记录为什么没有出现在虚拟中间表中呢?请读者参考上下文解答这个问题。

左连接

左连接的关键字是LEFT JOIN,我们的SQL改成如下所示:

结果会是如何呢?

左连接跟内连接稍有不同,仓库管理员大部分操作跟上面是一样的。不同点是,当他发现仓库B中没有跟A.N匹配的绳子的话,他会取出事先准备好的特殊绳子与A.N拼接,再放到仓库C中。这条特殊的绳子,长度跟B.N一样,结构也跟B.N相同,不同的是每个字段的值都是NULL。

也就是说,采用左连接,对左表的任何一条记录,不管右表中有没有匹配的记录,它都会显示出来。

左连接非常照顾左表中’不怎么受欢迎’的记录,它们不会被遗忘;对于左表中那些’很受欢迎’的记录,在右表中有N条匹配的那种,它们的连接效果跟内连接是一样的,也会在虚拟中间表中出现N次。

来看看左右两表只有一条记录的情况:

原表:

虚拟中间表:

张三这条记录并不能和美国这条记录匹配成功,可因为是左连接,左表的所有记录都会出现在虚拟中间表中,所以即便张三事实上没有成功牵手女嘉宾,但是节目组仍然会给张三一个安慰奖:全是NULL的另一半。

我们报表中用的最多的就是左连接, 因为它可以保证记录数,如果表中原记录数是M, 使用左连接跟其他表连接后,虚拟中间表的记录数会大于等于M,左表中的任何一条记录的出场次数,都会大于等于1。

拿人事模块的报表来说,人员主集上的记录数,也就是公司的总人数,常常会是非常硬的基准,如果我们要做一个人员花名册的报表,要展示公司所有人,20个字段的数据,其中包括最高学历,但是人员主集上张三的最高学历字段没有维护,我们如果用内连接,张三这条记录就不会展示了,实际上我们想要的效果是展示所有人,有些字段没维护,留空就好了,对此,左连接完美满足我们的需求。

下面是多条记录中左连接的例子

原表:

虚拟中间表:

如上图,左表中所有记录都出现了,因为张三在右表中成功匹配了三次,所以,他在虚拟中间表里出现了三次;李四虽然没有在右表中成功匹配,所以只在虚拟中间表中出现了一次,右半部分全是NULL值。

左连接的时候,容易有一个误解,就是会认为,左连接后虚拟中间表的记录数,是根据左表来的,在左表的记录占统治地位的时候,是的;但如果左表是个小表,基本上记录数是和右表差不多的。

时间: 2024-12-29 01:46:18

浅析表连接的相关文章

MySQL Study之--MySQL 表连接

MySQL Study之--MySQL 表连接 一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON condition table1:左表:table2:右表. JOIN 按照功能大致分为如下三类: INNER JOIN(内连接,或等值连接):取得两个表中存在连接匹配关系的记录. LEFT JOIN(左连接):取得左表(table1)完全记录,即是右表(table2)并无对应匹配记录

SQL Server三种表连接原理

http://msdn.microsoft.com/zh-cn/library/dn144699.aspx 简介 在SQL Server中,我们所常见的表与表之间的Inner Join,Outer Join都会被执行引擎根据所选的列,数据上是否有索引,所选数据的选择性转化为Loop Join,Merge Join,Hash Join这三种物理连接中的一种.理解这三种物理连接是理解在表连接时解决性能问题的基础,下面我来对这三种连接的原理,适用场景进行描述. 嵌套循环连接(Nested Loop J

每天一点数据库之-----Day 9 表连接

每天一点数据库之-----Day 9 表连接 ----转载请注明出处:coder-pig 本节引言: 前面我们学习的都是针对一个表来进行操作的,上一节虽然学了UNION这个可以操作多个表 的关键字,但是又有两个限制(查询字段数目与数据类型要相同),本节就来学习通过表连接 来操作多个表!而表连接又有四种: 内连接,外连接,交叉连接与自连接,那么接下来开始本节学习! 数据准备: 在开始学习前,我们先准备一些数据,建三个表:T_Stu,T_Class,T_Dorm 建T_Stu表: CREATE TA

表连接查询与where后使用子查询的性能分析。

子查询就是在一条查询语句中还有其它的查询语句,主查询得到的结果依赖于子查询的结果. 子查询的子语句可以在一条sql语句的FROM,JOIN,和WHERE后面,本文主要针对在WHERE后面使用子查询与表连接查询的性能做出一点分析. 对于表连接查询和子查询性能的讨论众说纷纭,普遍认为的是表连接查询的性能要高于子查询.本文将从实验的角度,对这两种查询的性能做出验证,并就实验结果分析两种查询手段的执行流程对性能的影响. 首先准备两张表 1,访问日志表mm_log有150829条记录(相关sql文件已放在

Mysql 表连接查询

1.内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符).包括相等联接和自然联接.     内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行.例如,检索 students和courses表中学生标识号相同的所有行.       2.外联接.外联接可以是左向外联接.右向外联接或完整外部联接.     在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:     1)LEFT  JOIN或LEFT OUTER JOIN     左向外联接的结果集包括  LEF

Mysql表连接

当需要同时显示多个表中的字段时,就可以用表连接来实现这样的功能. 从大类上分,表连接分为内连接和外连接,它们之间的最主要区别是內连接仅选出两张表中互相匹配的记录,而外连接会选出其他不匹配的记录.我们最常用的是内连接. 例如:查询出所有雇员的名字和所在部门名称,因为雇员名称和部门分别存放在表emp 和dept 中,因此,需要使用表连接来进行查询: select ename,deptname from emp,dept where emp.deptno=dept.deptno; ename是表emp

oracle 表连接 - hash join 哈希连接

一. hash 连接(哈希连接)原理 指的是两个表连接时, 先利用两表中记录较少的表在内存中建立 hash 表, 然后扫描记录较多的表并探測 hash 表, 找出与 hash 表相匹配的行来得到结果集的表连接方法. 哈希连接仅仅能用于等值连接条件(=). 如果以下的 sql 语句中表 T1 和 T2 的连接方式是哈希连接, T1 是驱动表 select * from T1, T2 where T1.id = T2.id and T1.name = 'David'; oracle 运行过程例如以下

MySQL多表查询之外键、表连接、子查询、索引

一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, 外键可以有重复的, 可以是空值,用来和其他表建立联系用的.所以说,如果谈到了外键,一定是至少涉及到两张表.例如下面这两张表: 上面有两张表:部门表(dept).员工表(emp).Id=Dept_id,而Dept_id就是员工表中的外键:因为员工表中的员工需要知道自己属于哪个部门,就可以通过外键Dep

表连接Join

--表连接Join--使用子查询select StudentNo,StudentName,(select classname from Classes where ClassId=Student.ClassId) from Student--使用from多表的方式select Student.StudentNo,Student.StudentName,Classes.classnamefrom Student,Classeswhere student.ClassId=classes.ClassI