SQL中除运算一定要完成目标的理由用exists才能完成吗?

【读书笔记】谨防SQL中的两个使用误区:整型相除及in/exists -
- ITeye技术网站
博客分类:
1. 在SQL Server中整型相除是取整(舍小数),如果要取小数且限制位数,可以用convert(numeric(10,2),a*1.0/b)或是cast(a*1.0/b as numeric(10,2))的方式得到.
2. 对于in/exists(clause)有4点需要注意:
(1) 含义上来说,in/exists都是取的交集,not in/exists都是取的差集.
(2) 语法上来说:
in: where column_name (not) in(clause)
exists: where (not) exists(clause)
(3) 原理上来说:
in: 把外表和内表作hash连接,确定给定的值是否与子查询或列表中的值相匹配. 也就是说,查询clause返回的结果集中是否存在column_name的行(感觉就是数组中是否存在这个值).
exists: 先对where前的主查询进行查询,然后用主查询的结果一个一个的代入exists的查询进行判断,如果为真则输出当前这一条主查询的结果,否则不输出. 也就是说先对外表作loop循环,每次loop循环再对内表进行查询.
(4) 效率上来说:
in/exists: 如果查询的两个表大小相当,那么用in和exists差别不大. 如果一大一小,则子查询表大的用exists,子查询表小的用in. 因为开销应该集中在loop循环中,而不是进出循环---切换至下一行这样的开销.
not in/exists: 无论哪个表大,用not exists都比not in要快. 这是因为前者能用到表上的索引,而后者不能. 最致命的一点在于用not in很可能导致出现致命的Bug,如果子集任一记录为Null值,则用not in的整个查询结果也是空集,而not exists是正确结果集.
summary: 针对整个使用(not) in/exists来说,兼顾效率与正确性,最好使的只有一个,也即开发中使用最为广泛的not exists. 而我们使用(not) in较多的地方只有明确定义clause为一个'数组'(感觉上的数组),即(not) in('a','b','c')
附(not in导致Bug的实例):
create table t1(c1 int,c2 int)
create table t2(c1 int,c2 int)
insert into t1 values(1,2)
insert into t1 values(1,3)
insert into t2 values(1,2)
insert into t2 values(1,null)
select * from t1 where c2 not in(select c2 from t2)
select * from t1 where not exists(select c2 from t2 where t1.c2=t2.c2)
VincentZheng
浏览: 37165 次
来自: 成都人人网 - 抱歉
哦,抱歉,好像看不到了
现在你可以:
看看其它好友写了什么
北京千橡网景科技发展有限公司:
文网文[号··京公网安备号·甲测资字
文化部监督电子邮箱:wlwh@··
文明办网文明上网举报电话: 举报邮箱:&&&&&&&&&&&&结构化查询语言(Structured Query Language)简称SQL(发音:/'?s kju: '?l/ "S-Q-L"),结构化查询语言是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上 工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统, 可以使用相同的结构化查询语言作为数据输入与管理的接口。结构化查询语言语句可以嵌套,这使它具有极大的灵活性和强大的功能。
本文为大家讲解的是sql查询中EXISTS函数的用法 ,EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False,感兴趣的同学参考下.&
比如在Northwind数据库中有一个查询为
SELECT c.CustomerId,CompanyName FROM Customers c
WHERE EXISTS(
SELECT OrderID FROM Orders o WHERE o.CustomerID=c.CustomerID)&
EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False
EXISTS 指定一个子查询,检测 行 的存在。
语法: EXISTS subquery
参数: subquery 是一个受限的 SELECT 语句 (不允许有 COMPUTE 子句和 INTO 关键字)。
结果类型: Boolean 如果子查询包含行,则返回 TRUE ,否则返回 FLASE 。
例表A:TableIn
例表B:TableEx
(一). 在子查询中使用 NULL 仍然返回结果集
select * from TableIn where exists(select null)
等同于: select * from TableIn
(二). 比较使用 EXISTS 和 IN 的查询。注意两个查询返回相同的结果。
select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
select * from TableIn where ANAME in(select BNAME from TableEx)
(三). 比较使用 EXISTS 和 = ANY 的查询。注意两个查询返回相同的结果。
select * from TableIn where exists(select BID from TableEx where BNAME=TableIn.ANAME)
select * from TableIn where ANAME=ANY(select BNAME from TableEx)
NOT EXISTS 的作用与 EXISTS 正好相反。如果子查询没有返回行,则满足了 NOT EXISTS 中的 WHERE 子句。
EXISTS(包 括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS内部有一个子查询语句(SELECT ... FROM...), 我将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。
一种通俗的可以理解为:将外查询表的每一行,依次代入内查询作为检验,如果内查询返回的结果取非空值,则EXISTS子句返回TRUE,这一行行可作为外查询的结果行,否则不能作为结果。
分 析器会先看语句的第一个词,当它发现第一个词是SELECT关键字的时候,它会跳到FROM关键字,然后通过FROM关键字找到表名并把表装入内存。接着 是找WHERE关键字,如果找不到则返回到SELECT找字段解析,如果找到WHERE,则分析其中的条件,完成后再回到SELECT分析字段。最后形成 一张我们要的虚表。
WHERE关键字后面的是条件表达式。条件表达式计算完成后,会有一个返回值,即非0或0,非0即为真(true),0即为假(false)。同理WHERE后面的条件也有一个返回值,真或假,来确定接下来执不执行SELECT。
分 析器先找到关键字SELECT,然后跳到FROM关键字将STUDENT表导入内存,并通过指针找到第一条记录,接着找到WHERE关键字计算它的条件表 达式,如果为真那么把这条记录装到一个虚表当中,指针再指向下一条记录。如果为假那么指针直接指向下一条记录,而不进行其它操作。一直检索完整个表,并把 检索出来的虚拟表返回给用户。EXISTS是条件表达式的一部分,它也有一个返回值(true或false)。
在插入记录前,需要检查这条记录是否已经存在,只有当记录不存在时才执行插入操作,可以通过使用 EXISTS 条件句防止插入重复记录。
INSERT INTO TableIn (ANAME,ASEX)&
SELECT top 1 '张三', '男' FROM TableIn
WHERE not exists (select * from TableIn where TableIn.AID = 7)
EXISTS与IN的使用效率的问题,通常情况下采用exists要比in效率高,因为IN不走索引,但要看实际情况具体使用:
IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
Copyright &
All Rights Reserved &&&&&&}

我要回帖

更多关于 一定要出汗才能减肥吗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信