中国统计网 SQL太难?你离完全理解SQL就差这10步!( 二 )
SQL语言的核心是对表的引用
由于SQL语句语法顺序和执行顺序的不同 , 很多同学会认为SELECT中的字段信息是SQL语句的核心 。 其实真正的核心在于对表的引用 。 根据SQL标准 , FROM语句被定义为:<fromclause>::=FROM<tablereference>[{<comma><tablereference>}...]FROM语句的“输出”是一张联合表 , 来自于所有引用的表在某一维度上的联合 。 我们们慢慢来分析:FROMa,b上面这句FROM语句的输出是一张联合表 , 联合了表a和表b 。 如果a表有三个字段 , b表有5个字段 , 那么这个“输出表”就有8(=5+3)个字段 。 这个联合表里的数据是a*b , 即a和b的笛卡尔积 。 换句话说 , 也就是a表中的每一条数据都要跟b表中的每一条数据配对 。 如果a表有3条数据 , b表有5条数据 , 那么联合表就会有15(=5*3)条数据 。 FROM输出的结果被WHERE语句筛选后要经过GROUPBY语句处理 , 从而形成新的输出结果 。 我们后面还会再讨论这方面问题 。 如果我们从集合论(关系代数)的角度来看 , 一张数据库的表就是一组数据元的关系 , 而每个SQL语句会改变一种或数种关系 , 从而产生出新的数据元的关系(即产生新的表) 。 我们学到了什么?思考问题的时候从表的角度来思考问题提 , 这样很容易理解数据如何在SQL语句的“流水线”上进行了什么样的变动 。4
灵活引用表能使SQL语句变得更强大
灵活引用表能使SQL语句变得更强大 。 一个简单的例子就是JOIN的使用 。 严格的说JOIN语句并非是SELECT中的一部分 , 而是一种特殊的表引用语句 。 SQL语言标准中表的连接定义如下:<tablereference>::=<tablename>|<derivedtable>|<joinedtable>就拿之前的例子来说:FROMa,ba可能输入下表的连接:a1JOINa2ONa1.id=a2.id将它放到之前的例子中就变成了:FROMa1JOINa2ONa1.id=a2.id,b尽管将一个连接表用逗号跟另一张表联合在一起并不是常用作法 , 但是你的确可以这么做 。 结果就是 , 最终输出的表就有了a1+a2+b个字段了 。 (译者注:原文这里用词为degree , 译为维度 。 如果把一张表视图化 , 我们可以想象每一张表都是由横纵两个维度组成的 , 横向维度即我们所说的字段或者列 , 英文为columns;纵向维度即代表了每条数据 , 英文为record , 根据上下文 , 作者这里所指的应该是字段数 。 )在SQL语句中派生表的引用甚至比表连接更加强大 , 下面我们就要讲到表连接 。 我们学到了什么?思考问题时 , 要从表引用的角度出发 , 这样就很容易理解数据是怎样被SQL语句处理的 , 并且能够帮助你理解那些复杂的表引用是做什么的 。 更重要的是 , 要理解JOIN是构建连接表的关键词 , 并不是SELECT语句的一部分 。 有一些数据库允许在INSERT、UPDATE、DELETE中使用JOIN 。5
SQL语句中推荐使用表连接
我们先看看刚刚这句:FROMa,b高级SQL程序员也许学会给你忠告:尽量不要使用逗号来代替JOIN进行表的连接 , 这样会提高你的SQL语句的可读性 , 并且可以避免一些错误 。 利用逗号来简化SQL语句有时候会造成思维上的混乱 , 想一下下面的语句:FROMa,b,c,d,e,f,g,hWHEREa.a1=b.bxANDa.a2=c.c1ANDd.d1=b.bc--etc...我们不难看出使用JOIN语句的好处在于:安全 。 JOIN和要连接的表离得非常近 , 这样就能避免错误
更多连接的方式 , JOIN语句能去区分出来外连接和内连接等
我们学到了什么?记着要尽量使用JOIN进行表的连接 , 永远不要在FROM后面使用逗号连接表 。6
简约框线标题
SQL语句中 , 表连接的方式从根本上分为五种:EQUIJOIN
SEMIJOIN
ANTIJOIN
CROSSJOIN
DIVISION
EQUIJOIN这是一种最普通的JOIN操作 , 它包含两种连接方式:--Thistablereferencecontainsauthorsandtheirbooks.--Thereisonerecordforeachbookanditsauthor.--authorswithoutbooksareNOTincludedauthorJOINbookONauthor.id=book.author_id--Thistablereferencecontainsauthorsandtheirbooks--Thereisonerecordforeachbookanditsauthor.--...ORthereisan"empty"recordforauthorswithoutbooks--("empty"meaningthatallbookcolumnsareNULL)authorLEFTOUTERJOINbookONauthor.id=book.author_id这种连接关系在SQL中有两种表现方式:使用IN , 或者使用EXISTS 。 “SEMI”在拉丁文中是“半”的意思 。 这种连接方式是只连接目标表的一部分 。 这是什么意思呢?再想一下上面关于作者和书名的连接 。 我们想象一下这样的情况:我们不需要作者/书名这样的组合 , 只是需要那些在书名表中的书的作者信息 。 那我们就能这么写:--UsingINFROMauthorWHEREauthor.idIN(SELECTbook.author_idFROMbook)--UsingEXISTSFROMauthorWHEREEXISTS(SELECT1FROMbookWHEREbook.author_id=author.id)尽管没有严格的规定说明你何时应该使用IN , 何时应该使用EXISTS , 但是这些事情你还是应该知道的:IN比EXISTS的可读性更好
推荐阅读
- 中国科学报|无创血检可提前4年发现癌症
- 中国北斗横空出世纪实
- 中国青年网|如何入环火轨道,揭秘“天问一号”如何在太空保持轨道
- 一萌娱乐|美国12500公里,俄罗斯16000公里,中国,三国导弹射程
- 视听中国|伊外长强烈谴责,美军战机骚扰伊朗客机画面公开
- 中国青年网|指其策划设拉子清真寺爆炸,伊朗称拘捕涉美“恐怖组织”头目
- 中国青年网|有哪些不为人知的故事?,北斗心脏精度每三百万年差1秒
- IT之家|最强中国“心”!北斗心脏精度每三百万年差1秒
- 上游新闻|精度达到2-3米,北斗系统发言人:中国北斗攻克160余项关键技术
- 烽火营|中国导弹仅够用2天?俄罗斯答案打脸印度专家,如果爆发战争
