热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

通过一个小问题来学习SQL关联查询

原话题:是关于一个leftjoin的,没有技术难度,但不想清楚不一定能回答出正确答案来:TabA表有三个字段Id,Col1,Col2且里面有一条数据1,1,2TabB表有两个字段Id,Col1且里面有四条数据问题:如下语句会返回多少条数据?在不写测试脚本的情况下,如果你

原话题: 是关于一个left join的,没有技术难度,但不想清楚不一定能回答出正确答案来: TabA表有三个字段Id,Col1,Col2 且里面有一条数据1,1,2 TabB表有两个字段Id,Col1且里面有四条数据 问题: 如下语句会返回多少条数据? 在不写测试脚本的情况下 ,如果你

原话题:

是关于一个left join的,没有技术难度,但不想清楚不一定能回答出正确答案来:

TabA表有三个字段Id,Col1,Col2 且里面有一条数据1,1,2

TabB表有两个字段Id,Col1且里面有四条数据

问题:

如下语句会返回多少条数据? 在不写测试脚本的情况下,如果你能在5分钟内准备回答出答案,且能说出些所以然来(及不是凭感觉猜出来的结果),那么请继续看后面的问题。

Select * from TabA a Left join TabB b1 on a.Col1=b1.Col1 Left join TabB b2 on a.Col2=b2.Col1

延深问题:

现在表A多增加一条数据2,3,4 ,此时再运行上面的语句会几条数据?如果你能在2分钟内回答出正常答案,那么请继续看后面的问题。

理论问题:

我发现就上面这个问题不少人回答不正确,这其中也包括我自己。为什么如此简单的问题往往会回答错误,我认为可能有如下原因:

对于第一种情况的人,短时间内无法解决,只有通过自身的学习来补救,对于第二种情况的人就需要稍微学习一些基本的理论知识就够用,对于第三种情况的人是一个态度问题。

left join的概念

简单来讲就是以左表做为外层循环表,每条每条去内层表去查找匹配记录,如果找到就返回join好的值,如果没找到返回外层表的值,内层表统一赋值为null。这里之所以说成简单来讲,是因为我是拿嵌套循环的例子来分析,因为这比较容易让非SQL方面的程序员明白,毕竟对于.net程序员来讲编写双层或者多层循环的例子会很多。而对于hash匹配以及合并联接的应用场景在.net程序中相对较少,类似如下的双层循环。

foreach(var colA in tabA) { foreach(var colB in tabB) { if(colA==colB) { ...... } } }

这里需要注意下,上面说到的外层表的记录循环去内层表查找时,这里有个问题,看这条语句:

Select * from TabA a Left join TabB b1 on a.Col1=b1.Col1

这里的TabA 就是我这里讲的外层表,TabB就是内层表,外层表就一行数据,内层表有4行数据,从上面给出的数据来看,用来做等值判断的条件是外层表的Col1字段与内层表的Col1字段,拿外层表的Cole=1这行数据去内层表查询时,内层表的第一条数据符合条件,其它三条不符合,此时的结果会是下面的哪一种呢?

  • 4条记录
  • a.Id a.Col1 a.Col2 b.Id b.Col1

    1 1 2 1 1

    1 1 2 null null

    1 1 2 null null

    1 1 2 null null

  • 一条记录
  • a.Id a.Col1 a.Col2 b.Id b.Col1

    1 1 1 2 1

    这要理解当在内层表中找到数据以及找不到数据的区别,我们拿外层表Col1=1这条数据去内层表查找时,需要查找4次,其中有一条符合,三条不符合,这说明找到了匹配数据,所以只返回匹配的数据行,即一条数据,而不会出现上面的第一种结果返回4条数据。

    这是我当时遇到这个问题时产生的误解。

    再看后面的那个left join

    Select * from TabA a Left join TabB b1 on a.Col1=b1.Col1 Left join TabB b2 on a.Col2=b2.Col1

    容易产生的问题,再进行第二次left join 的时候,外层表是TabA原始表呢还是第一次left join 之后的结果集呢? 看下我列出来的表头,就很容易理解了,这里的a.Col2就是第一次left join后的结果集。( a.Id a.Col1 a.Col2 b.Id b.Col1)

    我们可以做下测试,这里使用inner join来做测试,,因为这加容易比较出差异,运行下面的语句,此时TabA中有两条数据,就是上面延深问题中添加的2,3,4这条。

    Select * from TabA a inner join TabB b1 on a.Col1=b1.Col1 inner join TabB b2 on a.Col2=b2.Col1

    分两步来看:

    Select * from TabA a inner join TabB b1 on a.Col1=b1.Col1

    这里只会返回一条数据,因为inner join返回的交集。

    a.Id a.Col1 a.Col2 b.Id b.Col1

    1 1 2 1 1

    如果第二次join 时,如果连接的是原始表TablA,那么循环查询的次数应该是TabA的总条数2,但从下面的执行计划图可以分析出执行顺序。


    推荐阅读
    • 本文旨在为读者提供SPSS中t检验和卡方检验的简单明了介绍,帮助初学者快速掌握这两种常用统计方法的应用技巧。通过实际案例分析,加深对理论知识的理解。 ... [详细]
    • Working with Errors in Go 1.13
      作者|陌无崖 ... [详细]
    • 本文提供了一套实用的方法论,旨在帮助开发者构建能够应对高并发请求且易于扩展的Web服务。内容涵盖了服务器架构、数据库管理、缓存策略以及异步处理等多个方面。 ... [详细]
    • 深入理解Java NIO:基础概念与原理
      本文介绍了Java NIO(New Input/Output)的基本概念,包括同步与异步、阻塞与非阻塞等核心理念,以及NIO相对于传统IO的优势和应用场景。通过详细解析这些概念,帮助读者更好地理解和掌握NIO的使用。 ... [详细]
    • 请看|差别_Android 6.0 运行时权限处理解析
      请看|差别_Android 6.0 运行时权限处理解析 ... [详细]
    • 企业级 Java 应用的关键性能指标解析
      本文探讨了衡量企业级 Java 应用性能的四大核心指标:商业事务、外部服务、垃圾回收及应用布局。这些指标不仅直接影响用户体验,还关系到系统的稳定性和效率。 ... [详细]
    • 本文详细介绍了Java编程语言的基础知识,包括标识符的定义与规则、Java的关键字列表、基本数据类型及其特性、变量与常量的概念以及各种运算符的使用方法。 ... [详细]
    • Python基础入门:理解字符集与编码
      本文首先探讨了计算机的基本工作原理——二进制系统,进而深入介绍了字符集的概念及其在不同编码标准(如ASCII、GB2312、GBK、Unicode及UTF-8)中的应用。此外,文章还简要介绍了Python的安装、基本运行环境配置、变量定义、字符串处理、用户输入输出、条件判断及循环控制结构。 ... [详细]
    • 本文介绍如何在Mac和Windows操作系统中配置Sublime Text以直接运行PHP文件的方法,包括环境变量的设置及Sublime Text构建系统的创建。 ... [详细]
    • 代码规范与团队效率提升
      本文探讨了在项目开发中引入代码规范的重要性,尤其是在小型团队或创业公司中。通过具体的案例分析,强调了代码规范不仅能提高代码质量,还能促进团队协作和项目长期发展。 ... [详细]
    • Java中this关键字的多种应用场景解析
      在Java编程中,正确使用this关键字对于理解和编写高效代码至关重要。本文将详细介绍this关键字的不同使用场景,并通过实例帮助读者加深理解。 ... [详细]
    • 并发编程中的三大缺陷:数据竞争、原子性破坏与顺序违背
      本文探讨了并发编程中常见的三种缺陷——数据竞争、原子性破坏与顺序违背,分析了它们的成因及影响,并提供了相应的解决方案。 ... [详细]
    • 程序员易犯的六种错误,第二条就让人头疼不已
      每个程序员都有可能犯错,尤其是在编写代码时。本文列举了一些常见的编程错误,以及如何避免这些陷阱。来看看你是否也曾经遇到过这些问题。 ... [详细]
    • 本文探讨了在Python中如何利用Protobuf进行高效的数据序列化和反序列化,以及其相对于JSON等其他格式的优势。 ... [详细]
    • 作为一门广受赞誉的编程语言,Python因其简洁性和强大的功能,在Web开发、游戏设计、人工智能、云计算、大数据处理、数据科学、网络爬虫及自动化测试等多个领域得到广泛应用。本文将介绍2018年最受欢迎的五款Python框架,帮助开发者更好地选择合适的工具。 ... [详细]
    author-avatar
    诗人不失神
    这个家伙很懒,什么也没留下!
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有