子查询
子查询就是指的在一个完整的查询语句之中,嵌套若干个不同功能的小查询,从而一起完成复杂查询的一种编写形式,为了让读者更加清楚子查询的概念。
子查询返回结果
子查询可以返回的数据类型一共分为四种:
00001.
1. 单行单列:返回的是一个具体列的内容,可以理解为一个单值数据;
2. 单行多列:返回一行数据中多个列的内容;
3. 多行单列:返回多行记录之中同一列的内容,相当于给出了一个操作范围;
4. 多行多列:查询返回的结果是一张临时表;
在WHERE子句中使用子查询
在WHERE子句之中处理单行单列子查询、多行单列子查询、单行多列子查询。
单行单列子查询
示例一、查询公司之中工资最低的雇员的完整信息
--查询公司之中工资最低的雇员的完整信息SELECT * FROM emp eWHERE e.sal=(
SELECT MIN(sal)
FROM emp);
示例二、查询出基本工资比ALLEN低的全部雇员信息
-- 查询出基本工资比ALLEN低的全部雇员信息SELECT * FROM emp eWHERE e.sal<(
SELECT sal
FROM emp
WHERE ename='ALLEN'
);
示例三、查询基本工资高于公司平均薪金的全部雇员信息
--查询基本工资高于公司平均薪金的全部雇员信息SELECT *FROM emp eWHERE e.sal>(SELECT AVG(sal)FROM emp);
单行多列子查询。
示例四、查找出与ALLEN从事同一工作,并且基本工资高于雇员编号为7521的全部雇员信息,
--查找出与ALLEN从事同一工作,并且基本工资高于雇员编号为7521的全部雇员信息,SELECT *FROM emp e WHERE e.job=(
SELECT job
FROM emp
WHERE ename='ALLEN')
AND e.sal>(
SELECT sal
FROM emp
WHERE empno=7521);
示例五、查询与SCOTT从事同一工作且工资相同的雇员信息
SELECT *FROM emp e WHERE (e.job,e.sal) = (
SELECT job,sal
FROM emp
WHERE ename='SCOTT')
AND ename<>'SCOTT';
示例六、查询与雇员7566从事同一工作且领导相同的全部雇员信息
--查询与雇员7566从事同一工作且领导相同的全部雇员信息SELECT *FROM emp eWHERE (e.job,e.mgr) =(
SELECT job,mgr
FROM emp
WHERE empno=7566
);
示例七、查询与ALLEN从事同一工作且在同一年雇佣的全部雇员信息(包括ALLEN)
--查询与ALLEN从事同一工作且在同一年雇佣的全部雇员信息(包括ALLEN)SELECT *FROM emp eWHERE (e.job,to_char(e.hiredate,'yyyy'))=(
SELECT job,to_char(hiredate,'YYYY')
FROM emp
WHERE ename='ALLEN'
);
多行单列子查询
主要使用三种操作符:IN、ANY、ALL
IN操作
示例八、查询出与每个部门中最低工资相同的全部雇员信息
--查询出与每个部门中最低工资相同的全部雇员信息SELECT *FROM emp eWHERE e.sal IN(
SELECT MIN(sal)
FROM emp
GROUP BY deptno
);
示例九、查询出不与每个部门中最低工资相同的全部雇员信息
--查询出不与每个部门中最低工资相同的全部雇员信息SELECT *FROM emp eWHERE e.sal NOT IN(
SELECT MIN(sal)
FROM emp
GROUP BY deptno
);
ANY在使用中有如下三种使用形式:
=ANY:表示与子查询中的每个元素进行比较,功能与IN类似(然而<>ANY不等价于NOT IN)
>ANY:比子查询中返回结果的最小的要大(还包含了>=ANY)
<ANY:比子查询中返回结果的最大的要小(还包含了<=ANY)
示例十、查询出每个部门经理的工资
--查询出每个部门经理的工资
SELECT * FROM emp WHERE sal = ANY (
SELECT MIN (sal)
FROM emp
WHERE job='MANAGER'
GROUP BY deptno
);
示例十一、查询出每个部门大于经理的工资
--查询出每个部门大于经理的工资SELECT * FROM emp WHERE sal > ANY (
SELECT MIN (sal)
FROM emp
WHERE job='MANAGER'
GROUP BY deptno
);
示例十二、查询出每个部门小于经理的工资
--查询出每个部门小于经理的工资SELECT * FROM emp WHERE sal < ANY (
SELECT MIN (sal)
FROM emp
WHERE job='MANAGER'
GROUP BY deptno
);
ALL操作符有以下三种用法:
<>ALL:等价于NOT IN(但是=ALL并不等价于IN)
>ALL:比子查询中最大的值还要大(还包含了>=ALL)
<ALL:比子查询中最小的值还要小(还包含了<=ALL)
示例十三、查询出每个部门不等于经理的工资
--查询出每个部门不等于经理的工资SELECT * FROM emp WHERE sal <> ALL (
SELECT MIN (sal)
FROM emp
WHERE job='MANAGER'
GROUP BY deptno
);
示例十四、
SELECT * FROM emp WHERE sal < ALL (
SELECT MIN (sal)
FROM emp
WHERE job='MANAGER'
GROUP BY deptno
);
示例十五、
SELECT * FROM emp WHERE sal >ALL (
SELECT MIN (sal)
FROM emp
WHERE job='MANAGER'
GROUP BY deptno
);
空数据判断
在SQL之中提供了一个exists结构用于判断子查询是否有数据返回。如果子查询中有数据返回,则exists结构返回true,反之返回false。
示例十五、验证exists结构
--验证exists结构SELECT * FROM emp
WHERE EXISTS( --返回空值,没有内容输出
SELECT * FROM emp WHERE empno=9999); --没有这个编号的员工
示例十六、
SELECT * FROM emp
WHERE EXISTS(SELECT * FROM emp);--有内容将返回数据
示例十七、
SELECT * FROM emp
WHERE NOT EXISTS(SELECT * FROM emp);--有数据,但取返,没有内容输出
子查询
子查询是一种常用计算机语言SELECT-SQL语言中嵌套查询下层的程序模块。当一个查询是另一个查询的条件时,称之为子查询。
中文名
子查询
外文名
Sub Query
语 言
SELECT-SQL
命 令
WHERE子句中
目录
00001. 1 定义概念
00002. 2 语法结构
00001. ▪ IN子查询
00002. ▪ 比较运算符
00003. ▪ ANY子查询
00001. ▪ EXISTS子查询
00002. 3 使用规则
子查询定义概念
在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。当获得一个查询的答案需要多个步骤的操作,首先必须创建一个查询来确定用户不知道但包含在数据库中的值,将一个查询块嵌套在另一个查询块的WHERE字句或HAVING短语的条件中查询块称为子查询或内层查询。上层的查询块曾为父查询或外层查询。子查询的结果作为输入传递回“父查询”或“外部查询”。父查询将这个值结合到计算中,以便确定最后的输出。
SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。以层层嵌套的方式来构造程序正是SQL中"结构化"的含义所在。[1]
子查询是本质上就是一个完整 的SELECT 语句,它可以使一个 SELECT、SELECT...INTO 语句、INSERT...INTO 语句、DELETE 语句、或 UPDATE 语句或嵌套在另一子查询中。子查询的输出可以包括一个单独的值(单行子查询)、几行值(多行子查询)、或者多列数据(多列子查询)。
子查询语法结构
可用四种种语法来创建子查询:
1.带有比较运算符的子查询(sqlstatement)
comparison(>,<,=,!=)
2.带有ANY(some)或ALL谓词的子查询
comparison [ANY | ALL | SOME] (sqlstatement)
3.带有谓词IN的子查询
expression [NOT] IN (sqlstatement)
4.带有EXISTS谓词的子查询
[NOT] EXISTS (sqlstatement)
子查询IN子查询
在嵌套查询中,子查询的结构往往是一个集合,所以谓词 IN是嵌套查询中最经常使用的谓词。
如查询与“刘晨”同一个系学习的学生。先要确定刘晨所在系名,在用它来查找所在在这个系中学习的学生。
SELECT 学号,姓名,系名
FROM 学生表
WHERE IN
(SELECT 系名
FROM 学生表
WHERE 姓名=“刘晨”)
本例中,子查询的查询条件不依赖于父查询,称为不相关子查询。
用 IN 谓词,只能在主查询检索那些记录,在子查询中的某些记录也包含和它们相同的值。相反,可用 NOT IN 在主查询中检索那样的记录,在子查询中没有包含与它们的值相同的记录。下列示例返回有比 25%更低 的折扣的所有产品:
SELECT * FROM Products
WHERE ProductID NOT IN
(SELECT ProductID FROM OrderDetails
WHERE Discount >= .25);
子查询比较运算符
带有比较运算符的子查询是指父查询与子查询之间用比较运算符进行连接。当用户确切知道内层查询返回单个值时,可以用>、<、=、>=、<=、!=或<>等比较运算符。
例如上面的那个查询,由于一个学生只可能在一个系学习,也就是说内查询的结果是一个只,因此可以用=代替IN:SELECT 学号,姓名,系名
FROM 学生表
WHERE =
(SELECT 系名
FROM 学生表
WHERE 姓名=“刘晨”)
还可用子查询中的表名别名来查询子查询外的 FROM 子句的列表。下列示例返回工资等于或高于所有职位相同员工的平均工资的员工姓名。这张员工表的别名为 "T1":
SELECT LastName,
FirstName, Title, Salary
FROM Employees AS T1
WHERE Salary >=
(SELECT Avg(Salary)
FROM Employees
WHERE T1.Title = Employees.Title) Order by Title;
上例中AS保留词可选。如果子查询的查询条件依赖于父查询,这类子查询称为相关子查询,整个查询语句称为相关嵌套语句。
某些子查询在交叉表查询中是允许的,特别是谓词(那些在 WHERE 子句中的)。将子查询作为输出(那些列在 SELECT 中的)在交叉表查询中是不允许的。
子查询ANY子查询
子查询返回单值可以用比较运算符,但返回多值时要用ANY(有的系统用SOME)或ALL谓词修饰符。而使用ANY或ALL谓词的时候必须同时使用比较运算符。其语义如下:
>ANY 大于子查询结果中的某个值
>ALL 大于子查询结果中的所有值
<ANY 小于子查询结果中的某个值
<ALL 小于子查询结果中的所有值
>=ANY 大于等于子查询结果中的某个值
>=ALL 大于等于子查询结果中的所有值
<=ANY 小于等于子查询结果中的某个值
<=ALL 小于等于子查询结果中的所有值
=ANY 等于子查询结果中的某个值
=ALL 等于子查询结果中的所有值
!=(或<>)ANY 不等于子查询结果中的某个值
!=(或<>)ALL 不等于子查询结果中的所有值
ANY 或 SOME 谓词,它们是同义字,来检索主查询中的记录,这些记录要满足在子查询中检索的任何记录的比较条件。下列示例将返回全部单价比任何以 25% 或更高的折扣卖出的产品高的产品:
SELECT * FROM Products
WHERE UnitPrice > ANY
(SELECT UnitPrice FROM OrderDetails
WHERE Discount >= .25);
使用 ALL 谓词只检索主查询中的这些记录,它们满足在子查询中检索的所有记录的比较条件。如果将前一个示例中的 ANY 改为 ALL,查询只会返回单价比全部以 25% 或更高的折扣卖出的产品高的产品。这是更多的限制。
子查询EXISTS子查询
在 true/false 比较中使用 EXISTS 谓词(与可选的 NOT 保留字一道)来决定子查询是否会返回任何记录。[2] EXISTS代表存在量词ヨ,带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值"false"。
可以利用EXISTS来判断x∈S、S⊆R、S=R、S∩R非空等是否成立。
子查询使用规则
使用子查询的规则:
1)子查询必须“自身就是一个完整的查询”。即,它必须至少包括一个SELECT子句和FROM子句。
2)子查询不SELECT语句能包括在ORDER BY子句中。因为ORDER BY字句只能对最终查询结果排序,如果显示的输出需要按照特定顺序显示,那么ORDER BY子句应该作为外部查询的最后一个子句列出。
3)子查询“必须包括在一组括号中”,以便将它与外部查询分开。
4)如果将子查询放在外部查询的WHERE或HAVING子句中,那么该子查询只能位于比较运算符的“右边”。