项目开发中经常会使用到多张表进行关联查询,比如left join关联查询。

如果有一张表A和一张表B,查询语句 SELECT a.*,b.name from A a left join B b

On a.id = b.id 表示的含义的就是取A表独有的数据和A表和和B表共有的数据。

如上图所示,主表是A表,用A表去左关联查询B表,正常情况下会返回A表

的所有数据,不管这些数据在B表中是否存在。

  自己在写SQL语句的时候,突然发现查询条件的位置不一样,导致查询结果

出现很大的差异,让我很是疑惑。下面就来复现这个问题,首先创建两张表A和B.

表A插入3条数据,没有删除,is_deleted = 1 表示删除。

表B插入三条数据,删除其中两条数据。

自己查询的时候,想要查询两张表中没有删除的数据,于是写了第一个查询语句,结果如下,

自己一看这结果明显的不对,表A是主表,会取表中的所有数据,这种查询方式只取到一条数据。

然后换一种方式进行查询,如下

得到了自己想要的结果,A表的所有记录都需要,去关联B表查询的时候,如果匹配到就取B表

的结果,如果没匹配到就返回null。进一步改进的查询方式为,

为了更好的比较,自己又添加一个查询语句,把b表的是否删除的条件去掉,查询结果如下

  自己很好奇为什么会出现这种状况呢?查询条件写的位置不一样,就会导致查询结果不一致。

然后去网上寻找问题的答案,最终找到这个问题的答案:

on条件是在生成临时表的查询条件,不管连接的条件如何,最终都会返回主表的所有数据。

Where条件则是过滤掉临时表的数据,即是对最终数据的过滤,如果条件不符合则就直接过滤掉。

因此

SELECT

a.*, b. NAME

FROM

table_a a

LEFT JOIN table_b b ON a.id = b.id

WHERE

a.is_deleted = 0

AND b.is_deleted = 0;

这种查询方式就把后面两条数据过滤掉,因为其不满足 b.is_deleted = 0 的条件。

自己在查询的时候,只是想使用B表的有效数据进行关联查询,过滤条件就不能直接写在

Where条件中,需要写在on后面或者是使用子查询过滤掉。

  到此问题解决。以前写关联查询的时候,不需要考虑数据是否有效都是直接进行关联查询,

现在遇到问题,则需要特别小心,稍微不注意就会出现意想不到的错误,吸取这次的深刻教训。

参考菜鸟教程中的答案。

https://www.runoob.com/w3cnote/sql-different-on-and-where.html

left jon连接查询踩坑记的更多相关文章

  1. <<Python编程:从入门到实践>>踩坑记 Django

    <<Python编程:从入门到实践>>踩坑记 Django Django Python 19.1.1.5 模板new_topic 做完书上的步骤后,对主题添加页面经行测试,但是 ...

  2. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  3. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  4. Spark踩坑记——共享变量

    [TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...

  5. 记一次 Spring 事务配置踩坑记

    记一次 Spring 事务配置踩坑记 问题描述:(SpringBoot + MyBatisPlus) 业务逻辑伪代码如下.理论上,插入数据 t1 后,xxService.getXxx() 方法的查询条 ...

  6. [转]Spark 踩坑记:数据库(Hbase+Mysql)

    https://cloud.tencent.com/developer/article/1004820 Spark 踩坑记:数据库(Hbase+Mysql) 前言 在使用Spark Streaming ...

  7. Spark踩坑记——数据库(Hbase+Mysql)转

    转自:http://www.cnblogs.com/xlturing/p/spark.html 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库 ...

  8. Spark踩坑记:Spark Streaming+kafka应用及调优

    前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark streaming从k ...

  9. Vue + TypeScript + Element 搭建简洁时尚的博客网站及踩坑记

    前言 本文讲解如何在 Vue 项目中使用 TypeScript 来搭建并开发项目,并在此过程中踩过的坑 . TypeScript 具有类型系统,且是 JavaScript 的超集,TypeScript ...

  10. 【踩坑记】从HybridApp到ReactNative

    前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...

随机推荐

  1. 给你一颗“定心丸”——记一次由线上事故引发的Log4j2日志异步打印优化分析

    一.内容提要 自知是人外有人,天外有天,相信对于Log4j2的异步日志打印早有老师或者同学已是熟稔于心,优化配置更是信手拈来,为了防止我在这里啰里八嗦的班门弄斧,我先将谜底在此公布:log4j2.as ...

  2. 人工智能的新篇章:深入了解大型语言模型(LLM)的应用与前景

    人工智能的新篇章:深入了解大型语言模型(LLM)的应用与前景 LLM(Large Language Model)技术是一种基于深度学习的自然语言处理技术,旨在训练能够处理和生成自然语言文本的大型模型. ...

  3. 7.3 C/C++ 实现顺序栈

    顺序栈是一种基于数组实现的栈结构,它的数据元素存储在一段连续的内存空间中.在顺序栈中,栈顶元素的下标是固定的,而栈底元素的下标则随着入栈和出栈操作的进行而变化.通常,我们把栈底位置设置在数组空间的起始 ...

  4. 【游戏】C语言实现扫雷游戏(超详细备注和解释)

    C语言实现扫雷游戏 求个赞求个赞求个赞求个赞 谢谢 先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️ 文章目 ...

  5. (C语言)1到50的阶乘之和列表,参考用,洛谷:P1009 [NOIP1998 普及组] 阶乘之和

    1到50列表,阶乘之和 S=1!+2!+3!+⋯+n!(n≤50) 1::1 2::3 3::9 4::33 5::153 6::873 7::5913 8::46233 9::409113 10:: ...

  6. HDFS文件目录与LiveNodes 数量关系

  7. Mybatis的缓存过期机制和RedisCache

    MyBatis的缓存过期机制, flushInterval参数 在实际测试中, 发现Redis中的缓存数据TTL为-1, 在Hash中的key也无过期时间信息, 怀疑RedisCache的实现是否能正 ...

  8. JavaScript选择器

    Js选择器 JS选择器常用的有getElementById().getElementsByClassName().getElementsByName().getElementsByTagName(). ...

  9. Js中RegExp对象

    Js中RegExp对象 RegExp对象表示正则表达式,是由普通字符和特殊字符也叫元字符或限定符组成的文字模板,用于对字符串执行模式匹配. 描述 创建一个RegExp对象通常有两种方式,一种是通过字面 ...

  10. Oracle11gr2新增APPEND_VALUES提示

    在11.2中,Oracle新增了APPEND_VALUES提示,使得INSERT INTO VALUES语句也可以使用直接路径插入. 例子很简单: SQL> SELECT * FROM V$VE ...