Subquery typo with using in(转)
Subquery typo with using in
Do you use the following syntax?
- SELECT *
- FROM TABLE
- WHERE COLUMN IN (SELECT COLUMN FROM TABLE)
OR this?
- SELECT *
- FROM TABLE
- 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
- CREATE TABLE TestTable1 (id1 INT)
- CREATE TABLE TestTable2 (id2 INT)
- INSERT TestTable1 VALUES(1)
- INSERT TestTable1 VALUES(2)
- INSERT TestTable1 VALUES(3)
- INSERT TestTable2 VALUES(1)
- INSERT TestTable2 VALUES(2)
Now let's run the IN query
- SELECT *
- FROM TestTable1
- WHERE id1 IN (SELECT id2 FROM TestTable2)
id1 |
1 |
2 |
No problems here right?
What if by mistake you wrote id1 instead of id2?
- SELECT *
- FROM TestTable1
- 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
- SELECT *
- FROM t1
- WHERE EXISTS (SELECT * FROM TestTable2 t2 WHERE t2.id2 = t1.id1 )
id1 |
1 |
2 |
A JOIN will do the same as EXISTS
- SELECT t1.*
- FROM TestTable1 t1
- JOIN TestTable2 t2 ON t2.id2 = t1.id1
id1 |
1 |
2 |
Now let's try NOT IN
- SELECT *
- FROM TestTable1
- WHERE id1 NOT IN (SELECT id2 FROM TestTable2)
id1 |
3 |
No problem right?
Add a NULL value to the TestTable2 table
- INSERT TestTable2 VALUES(NULL)
Let's try running it again
- SELECT *
- FROM TestTable1
- 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?
- SELECT *
- FROM TestTable1 t1
- WHERE NOT EXISTS (SELECT * FROM TestTable2 t2 WHERE t2.id2 = t1.id1 )
id1 |
3 |
That works without a problem
What about a LEFT JOIN?
- SELECT t1.*
- FROM TestTable1 t1
- LEFT JOIN TestTable2 t2 ON t2.id2 = t1.id1
- 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(转)的更多相关文章
- 子查询 in 潜在的问题 - 建议最好别用
转至:http://wiki.lessthandot.com/index.php/Subquery_typo_with_using_in Subquery typo with using in Fro ...
- 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 不支持使 ...
- Oracle索引失效问题:WHERE C1='' OR C2 IN(SubQuery),并发请求时出现大量latch: cache buffers chains等待
问题描述: 项目反馈某功能响应时间很长,高峰期时系统整体响应很慢... 获取相应的AWR,问题确实比较严重,latch: cache buffers chains等待,因为这些会话SQL执行时间太长, ...
- [慢查优化]慎用MySQL子查询,尤其是看到DEPENDENT SUBQUERY标记时
案例梳理时间:2013-9-25 写在前面的话: 在慢查优化1和2里都反复强调过 explain 的重要性,但有时候肉眼看不出 explain 结果如何指导优化,这时候还需要有一些其他基础知识的佐助, ...
- 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 不支持使 ...
- DEPENDENT SUBQUERY” 和 “SUBQUERY”
http://blog.163.com/li_hx/blog/static/183991413201642410122327/ mysql> CREATE TABLE t1 (a INT, b ...
- linux之SQL语句简明教程---Subquery
我们可以在一个 SQL 语句中放入另一个 SQL 语句.当我们在 WHERE 子句或 HAVING 子句中插入另一个 SQL 语句时,我们就有一个 subquery 的架构. Subquery 的作用 ...
- cakephp , the subquery (2)
Cakephp 框架帮我们做了很多的工作,的确省了我们很多工作,提高了效率. 但是,碰到一些比较复杂的查询时,还是有些问题,官方的cookbook api 有说明一些详细的用法,但感觉还是不太够,有些 ...
- cakephp , the subquery
Cakephp 框架帮我们做了很多的工作,的确省了我们很多工作,提高了效率. 但是,碰到一些比较复杂的查询时,还是有些问题,官方的cookbook api 有说明一些详细的用法,但感觉还是不太够,有些 ...
随机推荐
- a标签不用点击模拟跳转url。
因为请求到数据前要判断用户是否是登录状态, 所以就想页面数据请求成功,就跳转到登录页面, 就用了location.href = url. 结果因为同源策略不能访问, 没想到a标签竟然可以直接跳转这个U ...
- C++基本规则
C++ 程序结构 让我们看一段简单的代码,可以输出单词 Hello World. #include <iostream> using namespace std; // main() 是程 ...
- shell_sctipts: 删除mysql备份到最后7日
目前,mysql的备份文件,经过一周左右清理,手动清理会比较费事,所以写了一个简单脚本来实现. 前提介绍: mysql备份文件放在/usr/bak/sql里面,sql文件的备份名称格式为: mysql ...
- 除了用作缓存数据,Redis还可以做这些
Redis应该说是目前最受欢迎的NoSQL数据库之一了.Redis通常被作为缓存组件,用作缓存数据.不过,除了可以缓存数据,其实Redis可以做的事还有很多.下面列举几例,供大家参考. 1.最新列表 ...
- VS2005常用快捷键
Visual C++ 2005有很多种快捷键的映射方案,有适合 Emacs 用户的,有适合 Visual C++ 6.0 用户的,也有 Visual Studio 2005的,下面的快捷键符合IDE默 ...
- [UE4] 虚幻4学习---UE4中的字符串转换
String Conversions: FString To FName FString To Int32 Float To FString FArrayReaderPtr To FString TA ...
- centos 7 mount usb hard disk(ntfs format)
1. yum install -y epel-release* 2. yum install -y ntfs-3g 3. 命令:fdisk -l (查看磁盘分区信息) [root@devserverg ...
- 不设目标也能通关「马里奥」的AI算法,全靠好奇心学习
在强化学习中,设计密集.定义良好的外部奖励是很困难的,并且通常不可扩展.通常增加内部奖励可以作为对此限制的补偿,OpenAI.CMU 在本研究中更近一步,提出了完全靠内部奖励即好奇心来训练智能体的方法 ...
- Wechall 部分WP
前言: 开始打CTF,掌握一些新的姿势与知识. 这里我选择的平台是Wechall.这里从简单到难 WP部分: Training: Get SourcedAnswer: 查看网页源代码 Training ...
- selenium+python自动化85-python3.6上SendKeys报错用PyUserInput取代
前言 python2上安装SendKeys库,对于不好定位的元素,用快捷键操作是极好的,那么在3.6上安装时,会报错 python3.6安装SendKeys报错 1.python3.6安装SendKe ...