子查询 in 潜在的问题 - 建议最好别用
转至:http://wiki.lessthandot.com/index.php/Subquery_typo_with_using_in
Subquery typo with using in
From Wiki
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!
子查询 in 潜在的问题 - 建议最好别用的更多相关文章
- 在SQL Server中为什么不建议使用Not In子查询
在SQL Server中,子查询可以分为相关子查询和无关子查询,对于无关子查询来说,Not In子句比较常见,但Not In潜在会带来下面两种问题: 结果不准确 查询性能低下 下面 ...
- (网页)在SQL Server中为什么不建议使用Not In子查询(转)
转自博客园宋沄剑 英文名:CareySon : 在SQL Server中,子查询可以分为相关子查询和无关子查询,对于无关子查询来说,Not In子句比较常见,但Not In潜在会带来下面两种问题: ...
- SQL Server中INNER JOIN与子查询IN的性能测试
这个月碰到几个人问我关于"SQL SERVER中INNER JOIN 与 IN两种写法的性能孰优孰劣?"这个问题.其实这个概括起来就是SQL Server中INNER JOIN与子 ...
- 【Java EE 学习 28 上】【oracle学习第二天】【子查询】【集合运算】【几种数据库对象】
一.子查询 1.为什么要使用子查询:问题不能一步求解或者一个查询不能通过一步查询得到. 2.分类:单行子查询和多行子查询. 3.子查询的本质:一个查询中包含了另外一个或者多个查询. 4.使用子查询的规 ...
- mysql sql_safe_updates 不支持子查询的更新。
考虑到开发人员有时候不小心误更新数据,要求线上库的 MySQL 实例都设置 sql_safe_updates=1 来避免没有索引的 update.delete. 结果有一天开发发现下面的一个SQL 没 ...
- 【T-SQL基础】03.子查询
以前总是追求新东西,发现基础才是最重要的,今年主要的目标是精通SQL查询和SQL性能优化. 本系列[T-SQL基础]主要是针对T-SQL基础的总结. [T-SQL基础]01.单表查询-几道sql查询题 ...
- SQL Server调优系列基础篇(子查询运算总结)
前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...
- MySQL数据库学习笔记(六)----MySQL多表查询之外键、表连接、子查询、索引
本章主要内容: 一.外键 二.表连接 三.子查询 四.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复 ...
- mysql in 子查询 效率慢 优化(转)
mysql in 子查询 效率慢 优化(转) 现在的CMS系统.博客系统.BBS等都喜欢使用标签tag作交叉链接,因此我也尝鲜用了下.但用了后发现我想查询某个tag的文章列表时速度很慢,达到5秒之久! ...
随机推荐
- HTML5 Canvas ( 图形的像素操作 ) getImageData, putImageData, ImgData.data
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- DDoS攻防战 (一) : 概述
岁寒 然后知松柏之后凋也 ——论语·子罕 (此图摘自<Web脚本攻击与防御技术核心剖析>一书,作者:郝永清先生) DDoS,即 Distributed Denial of Servi ...
- 使用示例带你提前了解 Java 9 中的新特性
使用示例带你提前了解 Java 9 中的新特性 转载来源:https://juejin.im/post/58c5e402128fe100603cc194 英文出处:https://www.journa ...
- EasyMock使用总结
最重要的事说在前面:遇到一个你不熟悉的知识,一定要去官网仔仔细细的看官方文档!一定要仔仔细细!一定要!(尔康鼻孔脸..) 正篇: 一.使用 首先,当然是添加依赖,有人用maven,有人用ant或者ma ...
- Session的作用和使用场景
1.session何时被创建? 客户首次访问服务器时,回话session对象被创建并分配一个唯一的Id,同时id号发送到客户端,并存入cookie,使得客户端session对象和服务器端一致. 2.如 ...
- js中常用的内部函数的使用
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- DNS使用的是TCP协议还是UDP协议
原文:http://benbenxiongyuan.iteye.com/blog/1088085 DNS同时占用UDP和TCP端口53是公认的,这种单个应用协议同时使用两种传输协议的情况在TCP/IP ...
- input radio 与label文字对齐
input{ vertical-align:middle; margin-bottom:2px; *margin-bottom:2px; } 原地址
- Python oct() 函数
Python oct() 函数 Python 内置函数 描述 oct() 函数将一个整数转换成8进制字符串. 语法 oct 语法: oct(x) 参数说明: x -- 整数. 返回值 返回8进制字符 ...
- np.identity()
二.np.identity()这个函数和之前的区别在于,这个只能创建方阵,也就是N=M 函数的原型:np.identity(n,dtype=None) 参数:n,int型表示的是输出的矩阵的行数和列数 ...