一、用SQL自连接查询处理列之间的关系

SQL自身连接,可以解决很多问题。下面举的一个例子,就是使用了SQL自身连接,它解决了列与列之间的逻辑关系问题,准确的讲是列与列之间的层次关系。SQL代码如下:

 SELECT FIRST.CNumber, SECOND.PCNumber
FROM Course FIRST, Course SECOND
WHERE FIRST.PCNumber=SECOND.CNumber;

 在这个代码中,只涉及到一个表,即课程信息表COURSE(CNumber, CName, PCNumber),其中CNumber是该课程的课程号,PCNumber是该课程的先修课课程号。在FROM子句中,为Course表起了两个不同的别名,即FIRST和SECOND,即为Course表创建了两个不同的实例。查询时,使用了条件语句WHERE,要求FIRST表中的先修课号PCNumber同SECOND表中的课程号CNumber相同,而查询所需要的结果,是FIRST表的课程号CNumber和SECOND表中的PCNumber,那么查询结果,就应该是FIRST表中的课程号CNumber和该课程号所对应的间接先修课课程号。
  
  同样的查询,如果不使用自连接,而纯粹是对单表本身进行操作,那将是非常困难的。假设在这个表中,有两个元组(cnumber1, cname1, pcnumber1)和(cnumber2, cname2, pcnumber2),其中,pcnumber1=cnumber2。在同一个COURSE表上,关于课程号的信息,只有CNumber和PCNumber这两个属性,它们只能表示一个课程号(cnumber1)和该课程号直接先修课(pcnumber1=cnumber2)的一层关系。而间接先修课,需要求出cnumber1和pcnumber2的关系,这是一个二层关系。对于这个只能表示一层关系的表而言,如果纯粹对单表进行操作而不使用自然连接,那么一个可行的方案是,为Course表再增加一个列PPCNumber,令该列表示间接先修课,那么,通过三个列,就可以表示这种二层关系了。
  通过这个例子以及对这个例子的分析,我们可以初步得出结论,自连接查询,可以表示表中各列的层次关系。当所要查询的信息都出于同一个表,而又不能直接通过该表的各个列的直接层次关系得到最终结果的时候,那么应该考虑使用表的自连接查询。
  

二、SQL自连接查询表示其它关系

  除了处理前面例子中的列之间的层次关系之外,SQL自连接查询还可用于处理列之间的顺序关系、因果关系等多种逻辑关系。此外,SQL自身查询还可以用于处理单列本身的逻辑关系。下面的例子,就说明了对单列的逻辑关系的处理。

 SELECT FIRST.Num, FIRST Stop, SECOND.Stop
FROM Route FIRST, Route SECOND
WHERE FIRST.NUM=SECOND.NUM;

 这个代码中,只涉及到一个表Route(Num, Stop),这个表可以表示某一线路的火车的车站线路信息。Num表示该车的车次号,Stop表示该次车停靠的城市名称。上面的代码,可以求出某一线路的火车可以联通的任意两个城市的名称。
 在这里例子中,连接的操作对象只有Num这一个列,通过相同的车次号,找出该列车联通的任意两个城市的信息。在这个例子中,原来表Route中的每一个元组,只能表示车号和该车的某一站点的信息,实际上,这是“1Vs1”的映射关系。如果要表示两个站点的联通关系,那么就应该把两个“1Vs1”关系合并,形成“1Vs多”的关系。我们利用自连接,很容易地解决了这个关系扩充的问题。
下面的这里例子,是对单一的列进行连接处理:
 

 SELECT FIRST.Num, SECOND.Num, FIRST.Stop
FROM Route FIRST, Route SECOND
WHERE FRIST.Stop=SECOND.Stop;

  
  上面的SQL代码,求出了路经相同城市的车次的信息。原表中的车次和车站是“1Vs1”关系,通过自连接后,得到了车次和车站的“多Vs1”关系。

 一些自连接代码经典例子:

到目前为止,我们连接的都是两张不同的表,那么能不能对一张表进行自我连接呢?答案是肯定的。
有没有必要对一张表进行自我连接呢?答案也是肯定的。

表的别名:
一张表可以自我连接。进行自连接时我们需要一个机制来区分一个表的两个实例。
在FROM clause(子句)中我们可以给这个表取不同的别名, 然后在语句的其它需要使用到该别名的地方
用dot(点)来连接该别名和字段名。

我们在这里同样给出两个表来对自连接进行解释。
爱丁堡公交线路,

车站表:
stops(id, name)

公交线路表:
route(num, company, pos, stop)

关于这两个表更详细的解释可以参考这里:http://sqlzoo.cn/buses.htm

一、对公交线路表route进行自连接。

 SELECT * FROM route R1, route R2
WHERE R1.num=R2.num AND R1.company=R2.company

我们route表用字段(num, company)来进行自连接. 结果是什么意思呢?
你可以知道每条公交线路的任意两个可联通的车站。

二、用stop字段来对route(公交线路表)进行自连接。

 SELECT * FROM route R1, route R2
WHERE R1.stop=R2.stop;

查询的结果就是共用同一车站的所有公交线。这个结果对换乘是不是很有意义呢。

从这两个例子我们可以看出,自连接的语法结构很简单,但语意结果往往不是
那么容易理解。就我们这里所列出的两个表,如果运用得当,能解决很多实际问题,
例如,任意两个站点之间如何换乘。

 SELECT R1.company, R1.num
FROM route R1, route R2, stops S1, stops S2
WHERE R1.num=R2.num AND R1.company=R2.company
AND R1.stop=S1.id AND R2.stop=S2.id
AND S1.name='Craiglockhart'
AND S2.name='Tollcross'

  
  总结
  
  同其它连接相比,SQL自连接查询本身并没有什么特殊的。但是,在应用中,自连接查询因为其语法结构简单,而逻辑结构复杂,语义往往不是那么容易被人理解,因此,在使用时,经常令人觉得迷惑不解。但只要把自连接运用的得当,把单表看成是多表,牢固树立这一思维定式,我们会发现,自连接查询会为我们解决很多复杂的问题。

原文地址:https://www.cnblogs.com/Hadley-pu/p/sql_selfconnect.html

sql中自连接的使用的更多相关文章

  1. SQL中的连接(极客时间)

    SQL中的连接 关系型数据库的核心之一就是连接, 而在不同的标准中, 连接的写法上可能有区别, 最为主要的两个SQL标准就是SQL92和SQL99了, 后面的数字表示的是标准提出的时间. SQL92中 ...

  2. SQL中Round(),Floor(),Ceiling()函数的浅析

    项目中的一个功能模块上用到了标量值函数,函数中又有ceiling()函数的用法,自己找了一些资料,对SQL中这几个函数做一个简单的记录,方便自己学习.有不足之处欢迎拍砖补充 1.round()函数遵循 ...

  3. 关于sql中in 和 exists 的效率问题,in真的效率低吗

    原文: http://www.cnblogs.com/AdamLee/p/5054674.html 在网上看到很多关于sql中使用in效率低的问题,于是自己做了测试来验证是否是众人说的那样. 群众: ...

  4. 学习sql中的排列组合,在园子里搜着看于是。。。

    学习sql中的排列组合,在园子里搜着看,看到篇文章,于是自己(新手)用了最最原始的sql去写出来: --需求----B, C, F, M and S住在一座房子的不同楼层.--B 不住顶层.C 不住底 ...

  5. SQL中distinct的用法

    SQL中distinct的用法   1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...

  6. hibernate中java类的成员变量类型如何映射到SQL中的数据类型变化

    hibernate映射文件??.hbm.xml配置映射元素详解--Hibernate映射类型 在从Hibernate的java的成员类型映射到SQL中的数据类型,其内映射方式它满足,SQL可以自己调制 ...

  7. C#调用SQL中的存储过程中有output参数,存储过程执行过程中返回信息

      C#调用SQL中的存储过程中有output参数,类型是字符型的时候一定要指定参数的长度.不然获取到的结果总是只有第一字符.本人就是由于这个原因,折腾了很久.在此记录一下,供大家以后参考! 例如: ...

  8. sql中case when语句的使用-来自网摘文章

    Case具有两种格式.简单Case函数和Case搜索函数. --简单Case函数 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END ...

  9. SQL中inner join、outer join和cross join的区别

    对于SQL中inner join.outer join和cross join的区别简介:现有两张表,Table A 是左边的表.Table B 是右边的表.其各有四条记录,其中有两条记录name是相同 ...

随机推荐

  1. Notepad++如何编译、运行Java

    首先要让Notepad++编译和运行Java,前提是电脑里已经配置好了Java的环境(这里可以参考我博客里关于Java环境配置的那篇随笔). 在Notepad++上面的选项栏中找到 插件---> ...

  2. CharsRefIntHashMap并不比HashMap<String, Integer>快

    我模仿lucene的BytesRef写了一个CharsRefIntHashMap,实測效果并不如HashMap<String, Integer>.代码例如以下: package com.d ...

  3. 乐字节-Java8核心特性实战-接口默认方法

    JAVA8已经发布很久,是自java5(2004年发布)之后Oracle发布的最重要的一个版本.其中包括语言.编译器.库.工具和JVM等诸多方面的新特性,对于国内外互联网公司来说,Java8是以后技术 ...

  4. Spring《八》AOP/代理类定义

    Spring通知 Interception Around通知 MethodInterceptor类(方法执行前后通知) Before通知 MethodBeforeAdvice类(方法执行前通知) Af ...

  5. BS程序性能调优

    首先想到的是优化算法.改进技术.扩展设备去做优化.其实在讨论性能的时候,绕不开对业务的理解,不同的业务系统对性能的要求不同,优化方式也不一样.优化性能的前提是保证业务的正确性.我们平时关注的性能主要是 ...

  6. JS中数组的一些笔记

    今天工作时碰到一个需求,有两个数组arrayChild, arrayFather, 要求: 1.往数组arrayChild中放入一个元素: 2.将当前的数组arrayChild放入arrayFathe ...

  7. 常用JQUERY插件大全

    jQuery内容滚动插件-BoxSlider jQuery artDialog对话框插件 移动端日期选择组件 图像延迟加载库Echo.js 轮播图FlexSlider插件 Slick.js幻灯片使用方 ...

  8. vue2.0.js

     数据的渲染.数据同步  组件化.模块化 路由    ajax  数据流 Vue.js学习资源        中文官网:http://cn.vuejs.org/             源码:http ...

  9. Struts2学习笔记 - Part.02

    ================Struts2的国际化================程序国际化: 程序可以根据极其所在的国家.语言环境,自动显示当前国家.语言的内容国际化的本质是:查找.替换国际化的 ...

  10. React重点概要

    JSX语法: 1.ReactDOM.render:用于将模板转换为HTML语言,并插入指定的DOM节点: 语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析,HTML 语言 ...