前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >编写 SQL 的排除联接

编写 SQL 的排除联接

作者头像
白日梦想家
发布2020-07-20 11:19:56
1.2K0
发布2020-07-20 11:19:56
举报
文章被收录于专栏:SQL实现SQL实现

有两个表,就叫源表和目标表吧。它们有一个相同的字段,通过该字段可以把源表和目标表关联在一起,我们希望从源表中检索到的记录里的关联字段的值没有存在目标表中。举个例子,源表 dept,目标表 emp,获取 dept 表中部门编号不在 emp 表中的记录。在检查两张表的数据后,我们发现 emp 表中没有部门编号 40 的数据。

图1 emp 表的数

图2 dept 表的数据

实现这种的查询的方法有很多,不同的实现方式的性能也会不一样。我们就来看看都有哪些方法?

NOT IN

代码语言:javascript
复制
SELECT 
  * 
FROM
  dept 
WHERE deptno NOT IN 
  (SELECT 
    deptno 
  FROM
    emp)

这种实现方式需要注意一个点,就是在 not in 里面不能出现 NULL,如果出现 NULL 就会查不到结果。比如下面这条 SQL,没有数据返回。

代码语言:javascript
复制
SELECT 
  dname 
FROM
  dept 
WHERE deptno NOT IN 
  (SELECT 
    deptno 
  FROM
    emp 
  UNION ALL 
  SELECT 
    NULL)

为什么是这样呢?

因为在逻辑运算中,涉及到 NULL 的操作的结果仍为 NULLnot in 可以改写成 or 的形式,比如 deptno not in(10,NULL) 展开成 or 的表达式是:not (deptno = 10 or deptno = NULL),最终的表达式是 not NULL

NOT EXISTS

使用 not exists 可以避免由于目标表的关联列上出现 NULL 而查不出数据。

代码语言:javascript
复制
WITH e AS 
(SELECT 
  deptno 
FROM
  emp 
UNION ALL 
SELECT 
  NULL) 
SELECT 
  * 
FROM
  dept 
WHERE NOT EXISTS 
  (SELECT 
    NULL 
  FROM
    e 
  WHERE e.deptno = dept.deptno)

使用 not exists 的 SQL 的一般形式:

代码语言:javascript
复制
SELECT 
  目标列 
FROM
  源表 
WHERE NOT EXISTS 
  (SELECT 
    NULL 
  FROM
    目标表 
  WHERE 关联字段)

在 MySQL 5.6 之前,子查询的性能表现得比较差,因而就有人想着把子查询改成连接的方式以提高查询性能。

LEFT JOIN

通常,我们会想到使用 NOT INNOT EXISTS 做排除操作。其实,使用 LEFT JOIN 也可以达到相同的目的。

代码语言:javascript
复制
SELECT 
  d.* 
FROM
  dept d 
  LEFT JOIN emp e 
    ON e.deptno = d.deptno 
WHERE e.deptno IS NULL 

对于表达式 a left join b ,不管 b 表中是否有数据可以和 a 表匹配得上,a 表总是能返回所有数据。如果 b 表中没有数据能匹配得上 a 表,在查询结果中会使用 NULL 填充 b 表的列。因此,通过过滤条件 b.关联列 is NULL 可以找到只存在于 a 表中的数据。

总结

  1. 使用 not in 时要考虑到排除的值中是否有 NULL ,如果有,需要提前做过滤处理。
  2. not existsleft join 都可以用来做排除操作,可以任选一种方式实现,如果 SQL 的性能表现不佳,则可以换另外一种方式试试。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SQL实现 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • NOT IN
  • LEFT JOIN
  • 总结
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档