关于SQL的应用,肯定离不开查询,而相对复杂的查询,总是离不开对表的连接,单个表操作的并不罕见,但是在应用环境大多数的查询都是针对2、3个表甚至更多的表7,至于连接,有内连接、外链接、交叉连接之分,每种连接方式都有各自的查询关键字去执行。此时犹记学时对这些概念含糊不分,不知所谓,总是认为课本的知识玄幻深奥,概念晦涩难懂,当然我也时常归咎于是本校师生随手“复印”的教材。

一、 内连接(通过关联信息匹配数据)

1.等值连接(=,有重复)  2.不等值连接(不等式、大小于)   3.自然连接(=,无重复,通过过滤条件)

SELECT * FROM a,b  WHERE a.id = b.id  --(ANSI连接语法,SQL92标准以前的写法)

SELECT * FROM a INNER JOIN b ON a.id = b.id   --( SQL92标准写法)

二、 外连接

1. 左连接(Left Join) 不管能否匹配到 on 的条件,左表数据均会完整显示

2. 右连接(Right Join) 不管能否匹配到on的条件,右表数据均会完整显示

3. 全连接(Full Join)  一定条件下(列名、列数一致),可用Union all 代替

当出现多个外链接(三路外连接)时,比如,需要连接两个Left Join

则,A表由5条数据,第一次Left 结束结果是5条,第二次 Left 结束之后结果仍然还是为5条

三、交叉连接(笛卡尔积)

实际应用中很少接触,查询结果初看乱七八糟,互相匹配,也是所有Join 都要执行的第一个步骤

SELECT * FROM a CROSS JOIN b 

以上只是些许概念,课本上网上都能查到,实际上在做这些查询的时候,往往伴随着条件的过滤,想要写好SQL,第一步是要明白这些条件的执行顺序

SQL的执行顺序:from > join > on  > where > group by  >  having >  select  >  distinct > order by  > limit

至于比较混淆的几点:

① Where 和 On 的区别 (Inner中无差别)

首先搞清楚Left 和 Right 两个查询的内部执行顺序  1.笛卡儿积    2. On 关联过滤     3. 添加外部行(Inner时无此操作)   4. Where过滤

然后我们根据实际数据来说明差别,如下两表:

根据表Student表中的ID 和StudentScore 表的UserCode 进行关联,分别写出如下语句

试想,三种sql语句的区别, 第一个没有加额外的过滤, 第二个是放在 On后面过滤,第三个是放在where 后过滤

select a.ID,b.ClassId,b.Score from Student a
left join StudetntScore b on a.ID = b.UserCode --条件放在On 后
select a.ID,b.ClassId,b.Score from Student a
left join StudetntScore b on a.ID = b.UserCode and b.ClassId is not null
--条件放在Where 后 
select a.ID,b.ClassId,b.Score from Student a
left join StudetntScore b on a.ID = b.UserCode where b.ClassId is not null

对应的查询结果如下

 

第一笔查询仅根据ID 关联的查询结果不难想象

第二笔查询虽然 只保留 b.ClassId is not null 的数据,其余的数据却在第三步添加外部行的时候又给加进来了,根据Left 左表完整的原则,补全后的栏位找不到值,自然为null

第三笔查询是在第一笔查询的结果上,where 检索  b.ClassId is not null 的数据

说到这里,还有一个地方需要注意,就是在检索后,select 选择列的时候,一定要分清楚关联列的所属表,否则,失之毫厘,擦之千里,比如,针对上面 第二个查询语句,如果随手手抖,如下:

select a.ID,b.ClassId,b.Score from Student a
left join StudetntScore b on a.ID = b.UserCode and b.ClassId is not null select b.UserCode,b.ClassId,b.Score from Student a
left join StudetntScore b on a.ID = b.UserCode and b.ClassId is not null

查询结果,俨然变成

      

列值就会出现变化,如果恰巧再对数据进行去重,Distinct,第二个表结果- 数据就变成了5条,差别更大了,故,进行连接操作时,一定要仔细分析情况,避免入坑。

②  Where  和 Having 的区别

这一点其实是很好区分的,Having的使用 一定伴随着 聚合函数 Group by 的出现,Where 是对分组之前进行过滤,having 是对分组之后进行过滤

SQL 中的连接查询的更多相关文章

  1. SQL中的连接查询及其优化原则

    连接查询是SQL的主要任务,只有很好的掌握了连接查询及其优化方法才算是掌握了SQL的精髓所在.最近在面试中遇到了有关连接查询的问题,感觉回答的不是很好,总结一下. 具体示例请参考:http://www ...

  2. SQL中join连接查询时条件放在on后与where后的区别

    数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. 在使用left jion时,on和where条件的区别如下: 1. on条件是在生成临时表时使用的条 ...

  3. SQL多表连接查询

    SQL多表连接查询 本文主要列举两张和三张表来讲述多表连接查询. 新建两张表: 表1:student  截图如下: 表2:course  截图如下: (此时这样建表只是为了演示连接SQL语句,当然实际 ...

  4. SQL Server数据库————连接查询和分组查询

    SQL Server数据库————连接查询和分组查询 分组查询 select 列from  <表名> where  …… group by  列 注意:跟order  by一样group ...

  5. Hibernate-ORM:13.Hibernate中的连接查询

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客将会解释Hibernate中的连接查询(各种join) 一,目录 1.内链接 1.1显式内连接(inn ...

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

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

  7. oracle中的连接查询与合并查询总结

    连接查询: 连接查询是指基于多张表或视图的查询.使用连接查询时,应指定有效的查询条件,不然可能会导致生成笛卡尔积.如现有部门表dept,员工表emp,以下查询因查询条件无效,而产生笛卡尔积:   (各 ...

  8. SQL中的连接可以分为内连接,外连接,以及交叉连接 。

    SQL中的连接可以分为内连接,外连接,以及交叉连接 . 1. 交叉连接CROSS JOIN 如果不带WHERE条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积: 举例, ...

  9. SQL Server中的连接查询【内连接,左连接,右连接,。。。】

    在查询多个表时,我们经常会用“连接查询”.连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志. 什么是连接查询呢? 概念:根据两个表或多个表的列之间的关系,从这些表中查询数据 ...

随机推荐

  1. 20165336 实验三 敏捷开发与XP实践

    20165336 实验三 敏捷开发与XP实践 一.实验报告封面 课程:Java程序设计 班级:1653班 姓名:康志强 学号:20165336 指导教师:娄嘉鹏 实验日期:2018年4月28日 实验时 ...

  2. 20165336 2017-2018-2 《Java程序设计》第4周学习总结

    20165336 2017-2018-2 <Java程序设计>第4周学习总结 教材学习内容总结 第五章 使用extends来定义一个子类. Object类是所有类的祖先类. 当子类和父类不 ...

  3. linux 替换 sed命令 转载

    转载自这里,感谢原作者 sed 's/test/mytest/g' example.txt 表示将example.txt中的test文本全部替换为mytest 请注意这个命令sed 's/test/m ...

  4. es的scoll滚动查询技术

    如果一次性要查出来比如10万条数据,那么性能会很差,此时一般会采取用scoll滚动查询,一批一批的查,直到所有数据都查询完处理完 使用scoll滚动搜索,可以先搜索一批数据,然后下次再搜索一批数据,以 ...

  5. MATLAB中产生随机数的那些函数

    1.产生从imin~imax的m*n矩阵 randi([imin,imax],m,n); 2.产生1~n的无重复随机整数 randperm(n);

  6. MySQL 5.5 服务器变量详解(一)

    autocommit={0|1} 设定MySQL事务是否自动提交,1表示立即提交,0表示需要显式提交.作用范围为全局或会话,可用于配置文件中(但在5.5.8之前的版本中不可用于配置文件),属于动态变量 ...

  7. weblogic学习教程(一)

    一.简介 WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发.集成.部署和管理大型分布式Web ...

  8. PHP 类名::class含义

    自 PHP 5.5 起,关键词 class 也可用于类名的解析. 使用 ClassName::class 可以获取一个字符串,包含了类 ClassName 的完全限定名称.这对使用了命名空间的类尤其有 ...

  9. python 内置方法expandtabs 把字符串格式化成列表输出

    #!/usr/bin/python3 # -*- coding: utf-8 -*- test = "username\tmail\tage\nzhangsen\tzhangsen@qq.c ...

  10. Case when then esle end

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