更新时间:2024-08-11 17:53
在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。当获得一个查询的答案需要多个步骤的操作,首先必须创建一个查询来确定用户不知道但包含在数据库中的值,将一个查询块嵌套在另一个查询块的WHERE字句或HAVING短语的条件中查询块称为子查询或内层查询。上层的查询块曾为父查询或外层查询。子查询的结果作为输入传递回“父查询”或“外部查询”。父查询将这个值结合到计算中,以便确定最后的输出。
SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。以层层嵌套的方式来构造程序正是SQL
子查询是本质上就是一个完整 的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是嵌套查询中最经常使用的谓词。
如查询与“刘晨”同一个系学习的学生。先要确定刘晨所在系名,在用它来查找所在在这个系中学习的学生。
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 子句的列表。下列示例返回工资等于或高于所有职位相同员工的平均工资
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(有的系统用SOME)或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% 或更高的折扣卖出的产品高的产品。这是更多的限制。 在 true/false 比较中使用 EXISTS 谓词(与可选的 NOT 保留字一道)来决定子查询是否会返回任何记录。EXISTS代表存在量词ヨ,带有EXISTS谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值 可以利用EXISTS来判断x∈S、S⊆R、S=R、S∩R非空等是否成立。 使用子查询的规则: 1)子查询必须“自身就是一个完整的查询”。即,它必须至少包括一个SELECT子句和FROM子句。 2)子查询SELECT语句不能包括在ORDER BY子句中。因为ORDER BY字句只能对最终查询结果排序,如果显示的输出需要按照特定顺序显示,那么ORDER BY子句应该作为外部查询的最后一个子句列出。 3)子查询“必须包括在一组括号中”,以便将它与外部查询分开。 4)如果将子查询放在外部查询的WHERE或HAVING子句中,那么该子查询只能位于比较运算符的“右边”。