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 有说明一些详细的用法,但感觉还是不太够,有些 ...
随机推荐
- BASIC-16_蓝桥杯_分解质因数
代码示例: #include <stdio.h> int i = 0 ;int Primes(int a){ for (i = 2 ; i <= a/2 ; i ++) { if ( ...
- 从Qt谈到C++(一):关键字explicit与隐式类型转换
转载:果冻虾仁 提出疑问 当我们新建了一个Qt的widgets应用工程时.会自动生成一个框架,包含了几个文件. 其中有个mainwindow.h的头文件.就是你要操纵的UI主界面了.我们看看其中的一段 ...
- RDD之三:RDD创建方式
RDD创建方式 1)从Hadoop文件系统(如HDFS.Hive.HBase)输入创建.2)从父RDD转换得到新RDD.3)通过parallelize或makeRDD将单机数据创建为分布式RDD. 4 ...
- 关于pycharm导入其他项目时出现找不到python无法运行的问题
之前拿到一个别的人用scrapy写的一个爬虫想运行看看,然后就出了类似于这种错误(类似的,这个是网上找的),一直提示找不到XXX路径下的python,然后无法运行执行文件... 我一看这个简单,这种就 ...
- mysqldump备份脚本---待完善
1. 建立备份文件存放目录:/backup/mysql 2. 编写备份脚本: # vim ~/bak.sh ## 写入如下内容: #! /bin/bash DB1_NAME="db1&quo ...
- Python 天气预报+微信
""" Description: 需要提供以下三个信息,在申请到的微信企业号当中可以找到 agentid corpid corpsecret Author:Nod Dat ...
- OSPF两种组播地址的区别和联系
1.点到点网络: 是连接单独的一对路由器的网络,点到点网络上的有效邻居总是可以形成邻接关系的,在这种网络上,OSPF包的目标地址使用的是224.0.0.52.广播型网络, 比如以太网,Token Ri ...
- 高通QMI协议
QMI(Qualcomm MSM Interface,官方名称应该是Qualcomm Message Interface)是高通用来替代OneRPC/DM的协议,用来与modem通信. QMI协议定义 ...
- sorted()&enumerate()
d = {1:2,3:1,44:5,4:5,7:8}l = d.items() #转换为列表print(l) # dict_items([(1, 2), (3, 1), (44, 5), (4, 5 ...
- ERROR 1045 (28000): Access denied for user 'hive'@'localhost' (using password: YES)
[root@master native]# mysql -uhive -pEnter password: ERROR 1045 (28000): Access denied for user 'hiv ...