left join ... is null 的实际应用

简介: left join ... is null 的实际应用

虽然题目有点拗口难懂,不知我到底在解决什么问题。我通过例子的方法来说明,就会一目了然了。


最近在做的一个需求,其中一部分要求是:查询出有过什么什么的客户且过滤掉什么的客户,其实就是各种表的联结再加上一些过滤条件。这都不重要,重要的是,这两个过滤条件我写的很有问题。

如下:

假如有一个表tb_ftc(不是真实业务场景的表)

image.png

过滤条件1:剔除c_st=2,5的c_id;

过滤条件2:取ch_no有过1和2的记录;

过滤条件3:剔除ch_no=10的c_id。

 

我写的第一版:

select c_id,...
from tb_ftc
where c_st not in (2,5)
and ch_no in (1,2)
and ch_no!=10;

因为查出来的结果,即c_id要和其他表进行关联,然后发现,ch_no=10的c_id还是存在的。

原因是 ch_no in (1,2)这个条件执行了,但ch_no!=10没执行。也就是说,有过ch_no=1和ch_no=2的c_id被留下了,这个c_id要和其他表关联

image.png

实际上c_id=01023&23456通过c_id和其他表关联之后,ch_no=10还是存在的

image.png

于是有了第二版:

当时的思路是,既然第二个过滤条件没用上,那就把ch_no!=10的记录单独作为一个表与过滤前两个条件的表进行关联,于是有了下面这样的代码

select a.c_id,a.ch_no,b.ch_no
from
(select c_id,ch_no
from tb_ftc
where c_st not in (2,5)
and ch_no in (1,2)) a join
(select c_id,ch_no
from tb_ftc
where ch_no!=10) b
on a.c_id=b.c_id;

这版写完之后逻辑感觉完全没有问题

image.png

image.png

join得到:

image.png

去重:

image.png


然而,用c_id=01023、13132去关联其他表,ch_no=10的这个c_id还是存在即01023。


我理解的偏差就在,以为删掉了ch_no=10的c_id,但只是删掉了tb_ftc表中的c_id,忽略了一个c_id有多个ch_no。



后来仔细想了一下,这个问题的思路应该是,只要有ch_no=10的c_id,就直接删掉,即使这个c_id有ch_no=1&2的记录。


所以,首先将ch_no=10的c_id全部挑选出来,然后再从tb_ftc表中挑选不是ch_no=10的c_id,加上另外两个条件即可。

select c_id
from tb_tfc
where c_id not in(select c_id
from tb_tfc 
where ch_no=10)
and ch_no in(1,2)
and c_st not in (2,5)

但是 not in (select 子句)通常可以由left join 来替换,联结比子查询更高效。

所以最终版本是:

select a.c_id
from tb_tfc a left join 
(select c_id
from tb_tfc 
where ch_no=10) b
on a.c_id=b.c_id
where b.c_id is null
and ch_no in(1,2)
and c_st not in (2,5)

left join 查询精髓:查询出a表有但b表没有的记录

select a.id
from tb a
left join (select id,no
from tb 
where no=1) b
on a.id=b.id
where b.id is null;

其实对于熟悉sql的人说就是个小问题,但是对于一个从没写过复杂sql的我,各种联结子查询我就晕了。。。

相关文章
|
9月前
|
SQL Oracle 关系型数据库
解决:Oracle数据库中Left join on 后面为null时匹配不上
解决:Oracle数据库中Left join on 后面为null时匹配不上
131 0
|
Go
mssql sqlserver in 关键字在值为null的应用举例
原文:mssql sqlserver in 关键字在值为null的应用举例 转自:http://www.maomao365.com/?p=6873 摘要: 下文通过案例分析in 关键字在值为null的应用举例, 分析出not in关键字在null值产生的异常信息 如下所示: CREA...
773 0
|
SQL
Left JOIN时指定NULL列返回特定值
我们有时会有这样的应用,需要在sql的left join时,需要使值为NULL的列不返回NULL而时某个特定的值,比如0 这个时候,用is_null(field,0)是行不通的,会报错的,可以用ifnull实现,但是COALESE似乎更符合标准。
1152 0
|
3月前
|
机器学习/深度学习 SQL 关系型数据库
【MySQL进阶之路丨第十一篇】一文带你精通MySQL NULL值处理、正则表达式
【MySQL进阶之路丨第十一篇】一文带你精通MySQL NULL值处理、正则表达式
39 0
|
3月前
|
SQL 关系型数据库 MySQL
总结 vue3 的一些知识点:MySQL NULL 值处理
总结 vue3 的一些知识点:MySQL NULL 值处理
|
5月前
|
SQL 关系型数据库 MySQL
MySQL NULL 值处理
MySQL NULL 值处理
|
2月前
|
SQL 关系型数据库 MySQL
python在mysql中插入或者更新null空值
这段代码是Python操作MySQL数据库的示例。它执行SQL查询从表`a_kuakao_school`中选取`id`,`university_id`和`grade`,当`university_id`大于0时按升序排列。然后遍历结果,根据`row[4]`的值决定`grade`是否为`NULL`。若不为空,`grade`被格式化为字符串;否则,设为`NULL`。接着构造UPDATE语句更新`university`表中对应`id`的`grade`值,并提交事务。重要的是,字符串`NULL`不应加引号,否则更新会失败。
25 2
|
5月前
|
存储 关系型数据库 MySQL
Flink CDC中mysql cdc 抽取这个时间字段的值为null 有什么好的解决方案吗 ?
Flink CDC中mysql cdc 抽取这个时间字段的值为null 有什么好的解决方案吗 ?
104 0