在 SQL Server 数据库的 WHERE 语句中使用子查询
|
这是关于子查询语句的一系列文章中的第三篇。在这篇文章中我们将讨论WHERE语句中的子查询语句。其他的文章讨论了其他语句中的子查询语句。 本次课程中的所有例子都是基于Microsoft SQL Server Management Studio和AdventureWorks2012数据库的。读者可以阅读我的SQL Server使用入门学习使用这些免费的工具。 在WHERE语句中使用子查询在WHERE语句中使用子查询是非常常见的。常见的用法是用EXISTS或IN测试存在性。在某些情况下重新考虑查询语句并且使用JOIN是有意义的,但是在最终决定之前,应该好好学习一下这两种通过查询优化的形式。 比较修饰符ANY和ALL可以和greater than,less than,或者equals操作符一起使用。这样就提供了一种方式比较一个单值,例如一个列,一个或更多的子查询返回的结果。 现在我们详细讨论这些。 |
芝麻开花节节矮
|
Exist和Not ExistsEXISTS条件结合子查询使用.当子查询返回一个或多个记录的时候,它返回TRUE. EXISTS条件最简单的语法形式如下:
假设我们需要返回,所有由销售人员记录的,从年初至今,大于三百万美元的销售订单.为了达到这个效果,我们可以使用如下例子中的EXISTS子句:
执行这条SQL语句的时候,会作如下的对比:
EXISTS条件是一种成员条件,即只有返回结果它才返回TRUE.相反的,如果我们要测试非成员条件,我们可以使用NOT EXISTS. 当无记录返回时,NOT EXISTS返回TRUE.这样,如果我们想找出,所有由销售人员记录的,从年初至今,小于等于三百万美元的销售订单,我们可以使用如下的查询:
|
gones945
|
NULL是怎么回事?当一个子查询返回null值的时候,EXISTS会返回什么: NULL, TRUE, 还是 FALSE? 坦白讲,我也很吃惊. 我很确信它会返回NULL, 但让人吃惊的是,我获知它返回TRUE。 因此,如果你的子查询返回null值,EXISTS子句会返回TRUE。 下面的例子会返回所有的SalesOrderHeader行,因为WHERE子句返回TRUE:
当我们学习IN操作符的时候,我们会发现,这是EXISTS子句所独有的特性. IN 和 NOT IN我们首先在如何过滤查询结果的课程中学习IN操作符。在子查询中使用的时候,IN 和 NOT IN 子句是一样的。下面是那篇文章的小结。 |
gones945
|
IN 和 NOT IN 回顾IN操作符被看作是一个成员类型。成员类型允许在一条语句中进行多次匹配测试。例如,假如有公司领导的多个拼写形式,如“Owner”,“President”,和“CEO”。在这种情况下,你可以使用IN操作符来找到所有的匹配形式:
如果ContactTitle是“CEO”,“Owner"或者“President",上面的语句将匹配或者返回TRUE。为了使用IN操作符,需要使用逗号分隔测试项,并括在括号中。例子中完整的语句是:
|
gones945
|
在子查询中使用IN当在子查询中使用的时候,数据列表可以用子查询来代替。在这种情况下,使用子查询的优势是,它有助于让查询处于数据驱动的状态,同时更易于处理。 我的意思是,你无需硬编码数据。 例如,如果你正在做一个查询,需要查找销售最多的销售人员的订单,非子查询的方式使用IN的语句是:
但是,现在我们知道了子查询,我们可以使用下面的语句获取同样的数据:
其优势在于,随着销售人员销售的数据变化,返回的SalesPersonID的数据也跟着调整。 和其它的查询一样,你可以使用IN子句来创建一个关联子查询。这和EXIST子句使用的是相同的查询。 它返回了,从年初至今,所有销售人员记录的大于三百万美元的销售订单,但是现在我们使用IN子句:
如果在比较列表中测试值 找到了 ,IN返回TRUE。如果在比较列表中测试值 没有找到 ,NOT IN返回TRUE。采用和上面一样的查询,我们可以找到,从年初至今,所有销售人员记录的小于等三百万美元的销售订单,查询语句如下:
|
gones945
|
在IN中碰到NULL是怎么回事?当比较列表值包含NULL值的时候,和此列表比较的任何数据均返回false。 例如:
返回0行。这是因为IN子句总是返回false。和EXISTS比起来,即便子查询返回NULL,EXISTS还是返回true。 比较修饰符比较操作符,如大于,小于,等于和不等于,可以在WHERE子句中修改为更加有趣的方式,来完成比较。 使用 > 仅仅只能比较单一值 (标量值) ,你可以使用 > ANY 或者 > ALL 比较某列的值和子查询返回的列表数据。 |
gones945
|
使用 > ANY 修饰符比较操作符>ANY意味着大于一个或多个列表项的值。也就是说会大于列表内的最小值。因此公式
会在销售量大于1000时返回TRUE,等同于语句:
简化为:
注意:你可以看到某些查询使用SOME。查询语句在使用SOME时返回的结果等同于ANY。即>ANY相同于>SOME。 我们以adventure works数据库为例,查找可能在安全库存等级的产品列表。具体说就是我们要查询的是安全库存等级大于平均安全库存等级的产品列表。 使用查询语句:
子查询首先计算平均安全库存等级。它返回一个数值列表。然后对每一个产品行的安全库存等级对外查询比较。如果它大于一个或多个列表中的值,就会被包含在结果中返回。 |
2015
|
|
如我一样,你可能第一反应是>ANY是多余的,鸡肋。它就等同于>MIN(...),不是吗? 这是可以用ANY,却不能用MIN的示例语句:
并不能运行,而是返回一个错误, “Cannot perform an aggregate function on an expression containing an aggregate or a subquery.” [译者注:不能运行的原因是GROUP BY语句对聚合函数不能用常规关键字操作,而是用另一些代替,例如GROUP BY条件中遇到聚合函数时WHERE用HAVING替换。] 使用 > ALL 修饰符> ALL 修饰符是返回所有比内查询中结果都大的结果。 比较操作>ALL意味着要大于列表中最大的值。示例如下:
等同于:
对条件 Sales > 2500返回为TRUE 这个例子我们返回年初至今 奖金大于 所有销售收入小于$1000000人员的奖金 的销售人员名单:
|
2015
|
各种比较修饰符小结
你能使用各种比较修饰符进行其他的操作,比如判断相等。如下表格内的示例可以更加便于理解。有些组合可能没有意义,我还是全部列了出来。
示例中的子查询结果集仅包含了三个数值: 1,2,3.
某些比较的组合根本没用。比如“= ALL” 或 “<> ANY.”。工具在于人使用,如果你觉得MAX或MIN可以用就该用,ANY和ALL只出现在它该出现的地方。
我们今天讨论了我在子查询中使用EXISTS和NOT EXISTS的情况。我用了相当多的IN子句,但通常是在一个静态列表,而不是子查询中。
转载于开源中国社区 http://www.oschina.net/translate/get-ready-to-learn-sql-server-using-subqueries
在 SQL Server 数据库的 WHERE 语句中使用子查询的更多相关文章
- SQL Server调优系列基础篇(子查询运算总结)
前言 前面我们的几篇文章介绍了一系列关于运算符的介绍,以及各个运算符的优化方式和技巧.其中涵盖:查看执行计划的方式.几种数据集常用的连接方式.联合运算符方式.并行运算符等一系列的我们常见的运算符.有兴 ...
- SQL Server 数据库部分常用语句小结(三)
21.SQL运行Log的读取 .EXEC xp_readerrorlog 0,1,null,null,'开始时间','结束时间' 22. Alwayson 状况及传输情况监控 SELECT ar.re ...
- 数据库开发基础-SQl Server 主键、外键、子查询(嵌套查询)
主键 数据库主键是指表中一个列或列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过它可强制表的实体完整性.当创建或更改表时可通过定义 PRIMARY KEY约束来创建主键.一个 ...
- 在update语句中使用子查询
在update 中的 where 子句中使用子查询: UPDATE mg_page_log as a SET page_num=1 WHERE id in( SELECT id from mg_ ...
- Access数据库和SQL Server数据库在实际应用中的区别
1.在Access数据库中简历查询语句的步骤 --> 打开你的MDB --> 在数据库窗口中,点击“查询”,或在“视图”菜单中选择“数据库对象”-> “查询” --> 点击数据 ...
- sql server数据库将excel表中的数据导入数据表
一般有两种方法可以实现,一种是直接写sql语句,另外一种是利用sqlserver的管理工具实现.这里介绍的是后面一种方法. 步骤: 一.准备数据 1.将excel表另存为文本格式,注意文本格式需为ta ...
- SQL Server 数据库部分常用语句小结(二)
9. 查询备份还原数据库的进度. select command ,percent_complete ,est_time_to_go=convert(varchar,(estimated_complet ...
- SQL Server 数据库部分常用语句小结(一)
1. 查询某存储过程的访问情况 SELECT TOP 1000 db_name(d.database_id) as DBName, s.name as 存储名字, s.type_desc as 存储类 ...
- SQL Server数据库存在判断语句及系统表简介 转
Transact-SQL Exists Sentences--判断数据库是否存在IF EXISTS(SELECT * FROM master.sysdatabases WHERE name=N'库名' ...
随机推荐
- [宽度优先搜索] HDU 1372 Knight Moves
Knight Moves Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ...
- Java成员初始化顺序
//类装载时: 1, 基类static成员 2, 派生类static成员 //创建对象时: 3, 基类构造函数 4, 派生类构造函数
- CPU指令系统
CPU就是通过指令系统来操控寄存器然后实现读取数据的,所以我们必须介绍一下CPU的指令系统 如果我们知道指令的英文全称,这对我们理解指令的作用有很大帮助,所以贴出指令英文全称 接下来就是介绍一些主要的 ...
- struts2 log4j:WARN Please initialize the log4j system properly. 解决方法
在tomcat启动的时候,出现这个警告: log4j:WARN No appenders could be found for logger (org.apache.commons.digester. ...
- android技巧(一):如何方便知晓当前Activity?如何管理应用中的Activity?如何最佳的启动一个Activity?
1.如何方便知晓当前Activity? 可以不看代码根据当前界面就知道界面所在Activity的写法: 建立BaseActivity,继承自Activity,在BaseActivity的OnCreat ...
- laravel增删改查
基本想法是搭建一个FormController,所有以后需要配置生成后台的controller就继承这个FormController就好了.在FormController中定义属性: class Fo ...
- HDU 5234 DP背包
题意:给一个n*m的矩阵,每个点是一个蛋糕的的重量,然后小明只能向右,向下走,求在不超过K千克的情况下,小明最终能吃得最大重量的蛋糕. 思路:类似背包DP: 状态转移方程:dp[i][j][k]--- ...
- JavaScript 运行时错误: 无法获取未定义或 null 一种解决方案
脚本是肯定没有错误的!! 引用了高版本的jquery jquery-1.10.1.min.js 但在ie10下面就是报错 "JavaScript 运行时错误: 无法获取未定义或 null & ...
- PAT (Basic Level) Practise:1028. 人口普查
[题目链接] 某城镇进行人口普查,得到了全体居民的生日.现请你写个程序,找出镇上最年长和最年轻的人. 这里确保每个输入的日期都是合法的,但不一定是合理的——假设已知镇上没有超过200岁的老人,而今天是 ...
- sublimetext 使用正则表达式匹配中文
[\x{4e00}-\x{9fa5}] ============================================= 参考资料 1.在javascript下正确的\x4e00-\x9fa ...

