Subquery typo with using in

Do you use the following syntax?

 
  1. SELECT *
  2. FROM TABLE
  3. WHERE COLUMN IN (SELECT COLUMN FROM TABLE)

OR this?

 
  1. SELECT *
  2. FROM TABLE
  3. WHERE COLUMN NOT IN (SELECT COLUMN FROM TABLE)

Do NOT use that, it will cause problems sooner or later. Don't believe me? Let's take a look

First create these 2 tables and populate them with some sample data

 
  1. CREATE TABLE TestTable1 (id1 INT)
  2. CREATE TABLE TestTable2 (id2 INT)
  3. INSERT TestTable1 VALUES(1)
  4. INSERT TestTable1 VALUES(2)
  5. INSERT TestTable1 VALUES(3)
  6. INSERT TestTable2 VALUES(1)
  7. INSERT TestTable2 VALUES(2)

Now let's run the IN query

 
  1. SELECT *
  2. FROM TestTable1
  3. WHERE id1 IN (SELECT id2 FROM TestTable2)
id1
1
2

No problems here right?

What if by mistake you wrote id1 instead of id2?

 
  1. SELECT *
  2. FROM TestTable1
  3. WHERE id1 IN (SELECT id1 FROM TestTable2)

id1

1
2
3

Oops all 3 rows are returned, if you just run this SELECT id1 FROM TestTable2 you will get this error
Server: Msg 207, Level 16, State 3, Line 1
Invalid column name 'id1'.

So what happens? SQL Server sees column id1 and says "yes I have that it is in the TestTable1 table, I can use that"
What can we do? Use EXISTS because you will get an error instead of a wrong resultset

 
  1. SELECT *
  2. FROM t1
  3. WHERE EXISTS (SELECT * FROM TestTable2 t2 WHERE t2.id2 = t1.id1 )

id1

1
2

A JOIN will do the same as EXISTS

 
  1. SELECT t1.*
  2. FROM TestTable1 t1
  3. JOIN TestTable2 t2 ON t2.id2 = t1.id1

id1

1
2

Now let's try NOT IN

 
  1. SELECT *
  2. FROM TestTable1
  3. WHERE id1 NOT IN (SELECT id2 FROM TestTable2)

id1

3

No problem right?

Add a NULL value to the TestTable2 table

 
  1. INSERT TestTable2 VALUES(NULL)

Let's try running it again

 
  1. SELECT *
  2. FROM TestTable1
  3. WHERE id1 NOT IN (SELECT id2 FROM TestTable2)

Where are my rows? Nowhere, since NULL is not equal to anything including another NULL SQL just returns nothing

What happens when you use NOT EXISTS?

 
  1. SELECT *
  2. FROM TestTable1 t1
  3. WHERE NOT EXISTS (SELECT * FROM TestTable2 t2 WHERE t2.id2 = t1.id1 )

id1

3

That works without a problem

What about a LEFT JOIN?

 
  1. SELECT t1.*
  2. FROM TestTable1 t1
  3. LEFT JOIN TestTable2 t2 ON t2.id2 = t1.id1
  4. WHERE t2.id2 IS NULL

id1

3

That works without a problem also

So from now on use EXISTS, NOT EXISTS, JOIN and LEFT JOIN

DO NOT use IN or NOT IN ever again!

Subquery typo with using in(转)的更多相关文章

  1. 子查询 in 潜在的问题 - 建议最好别用

    转至:http://wiki.lessthandot.com/index.php/Subquery_typo_with_using_in Subquery typo with using in Fro ...

  2. MySQL----This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery

    This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'的意思是,这版本的 MySQL 不支持使 ...

  3. Oracle索引失效问题:WHERE C1='' OR C2 IN(SubQuery),并发请求时出现大量latch: cache buffers chains等待

    问题描述: 项目反馈某功能响应时间很长,高峰期时系统整体响应很慢... 获取相应的AWR,问题确实比较严重,latch: cache buffers chains等待,因为这些会话SQL执行时间太长, ...

  4. [慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时

    案例梳理时间:2013-9-25 写在前面的话: 在慢查优化1和2里都反复强调过 explain 的重要性,但有时候肉眼看不出 explain 结果如何指导优化,这时候还需要有一些其他基础知识的佐助, ...

  5. This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery 解决方法

    This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'的意思是,这版本的 MySQL 不支持使 ...

  6. DEPENDENT SUBQUERY” 和 “SUBQUERY”

    http://blog.163.com/li_hx/blog/static/183991413201642410122327/ mysql> CREATE TABLE t1 (a INT, b ...

  7. linux之SQL语句简明教程---Subquery

    我们可以在一个 SQL 语句中放入另一个 SQL 语句.当我们在 WHERE 子句或 HAVING 子句中插入另一个 SQL 语句时,我们就有一个 subquery 的架构. Subquery 的作用 ...

  8. cakephp , the subquery (2)

    Cakephp 框架帮我们做了很多的工作,的确省了我们很多工作,提高了效率. 但是,碰到一些比较复杂的查询时,还是有些问题,官方的cookbook api 有说明一些详细的用法,但感觉还是不太够,有些 ...

  9. cakephp , the subquery

    Cakephp 框架帮我们做了很多的工作,的确省了我们很多工作,提高了效率. 但是,碰到一些比较复杂的查询时,还是有些问题,官方的cookbook api 有说明一些详细的用法,但感觉还是不太够,有些 ...

随机推荐

  1. 创建一个包括菜单栏,工具栏,状态栏,文本编辑部件的经典GUI应用程序的骨架

    效果如下: 代码如下: #!/usr/bin/python3 # -*- coding: utf-8 -*- """ This program creates a ske ...

  2. onload属性使用方法

    onload事件属性是页面的图片文字等全部加载完毕后执行的事件 window.onload=fun1;function fun1(){    document.getElementsByTagName ...

  3. IE6 CSS高度height:100% 无效解决方法总结

    原文地址:http://www.cnblogs.com/huangyong8585/archive/2013/02/05/2893058.html   上面红色部分为 height:100%; 自动拉 ...

  4. js将UTC时间转化为当地时区时间

    js将UTC时间转化为当地时区时间(UTC转GMT)   我们在进行网站开发的时候有可能会涉及到国外的用户或者用户身在国外,这时就会存在时差问题,比如说我们在中国的时间是08:00,但是此时韩国的时间 ...

  5. javascript创建对象之寄生构造函数模式(六)

    这种模式的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象; 但是从表面上看,这个函数有很像典型的构造函数. function createHuman(name,s ...

  6. securecrt8注册码

    securecrt8注册码,两个可用 Name:meisiCompany:TEAM ZWTSerial Number:03-14-367662License Key:ACCFAX R9FHJ7 QZV ...

  7. win10 停留在启动画面

    这是由于部分电脑的主板不支持快速启动造成的,所以把快速启动功能关闭掉即可.具体操作步骤如下:控制面板--硬件和声音--电源选项--选择电源按钮的功能--选择“更改当前不可用的设置”,然后把“启用快速启 ...

  8. linnux-shell知识

    awk 是单行处理文本 正则: cat test.py | awk '/a/ {print $1}'  # 如果test.py中存在a这个字母,就打印所在行的第一列(注意是该列,不是该词).匹配成功, ...

  9. 动态html处理和及其图像识别

    爬虫(Spider),反爬虫(Anti-Spider),反反爬虫(Anti-Anti-Spider) 之间恢宏壮阔的斗争... Day 1 小莫想要某站上所有的电影,写了标准的爬虫(基于HttpCli ...

  10. (11/24) css进阶:Less文件的打包和分离

    写在前面:在前面我们对css打包和分离进行了描述.此节我们开始学习如何对less文件进行打包和分离. Less 是一门 CSS 预处理语言,它扩展了 CSS 语言,增加了变量.Mixin.函数等特性, ...