在 SQL Server 中,子查询是一项强大的功能,用于执行复杂查询并合并来自多个表或多个数据集的数据。在不同的业务场景和需求中,我们可以利用子查询将内部查询与外部查询的数据连接起来。在本文中,让我们一起来探讨什么是子查询,它可以在哪些地方使用,以及如何构建一个子查询。
子查询基础
子查询是嵌套在另一个查询或 SQL 语句内部的 ‘SELECT‘ 查询。子查询可以与 SELECT、INSERT、UPDATE 或 DELETE 语句一起使用,通常放置在外部查询(主查询)的 WHERE、HAVING 或 FROM 子句中。
#### 子查询通常采用以下几种格式:
> WHERE expression [NOT] IN (subquery)
>
>
>
> WHERE expression comparison_operator [ANY | ALL] (subquery)
>
>
>
> WHERE [NOT] EXISTS (subquery)
#### 子查询的一般语法如下:
> SELECT column_name(s)
>
>
>
> FROM table_name
>
>
>
> WHERE column_name operator
>
>
>
> (SELECT column_name
>
>
>
> FROM table_name
>
>
>
> WHERE condition);
子查询的规则
- 子query通常包含在外部查询的 WHERE 子句、HAVING 子句或 FROM 子句之后。我们也可以在 ‘Select‘ 语句中使用子查询来动态获取列值。
- 子查询必须始终嵌套在圆括号 ‘()‘ 内。
- 子查询可以与另一个子查询一起使用,形成嵌套查询。
- 子查询必须包含 SELECT 查询和带有 ‘WHERE‘ 条件的 FROM 子句。
- 如果子查询需要返回多行数据,则应使用多值运算符,如 IN、ALL、ANY 或 EXISTS。
- 子查询的选择列表中不允许使用 ntext、text 和 image 数据类型的列。
- 除了在使用 TOP 的情况外,子查询中不能使用 ORDER BY 命令。
- 在子查询中不能使用 COMPUTE 和 INTO 子句。
子查询的类型
根据使用方式和所需的数据结果,SQL Server 中使用了不同类型的子查询。让我们通过示例来详细了解常见的子查询类型。
以下是下文示例中将使用的表数据:
#### 产品表:
!ProductsTable产品表
#### 订单表:
!Orders Table订单表
1. 标量子查询
当一个子查询仅返回单个数据值(即单行单列)时,我们称之为标量子查询。下面是标量子查询的一个简单示例:
Select ProductID, ProductName,CategoryID,Price,
(Select Sum(Quantity) from OrderDetails O where O.ProductID=P.ProductID) As OrderValue
from Products P where CategoryID=2
在上述示例中,‘OrderValue‘ 是一个动态列值,它是在运行时根据 ‘Select‘ 语句中给出的子查询结果创建的。
上述查询的输出结果:
!Scalar Subquery标量查询示例
2. 单行或多行子查询
#### 单行:
在这种情况下,子query从外部查询 ‘WHERE‘ 子句后给定的子query中返回单行值或多行值。
#### 单行示例:
Select * from Products Where ProductID = (Select MAX(ProductID) from OrderDetails where OrderID =10250)
在上述示例中,子查询仅返回一个值。
上述单行查询的输出结果:
!Single row subquery 单行子查询示例输出
#### 多行示例:
Select * from Products Where ProductID IN (Select ProductID from OrderDetails where OrderID =10250)
在上述示例中,使用了 IN 运算符,子查询可以返回多行。还有其他运算符如 NOT IN、ANY、ALL、EXISTS 或 NOT EXISTS 也可以返回多行。
上述多行查询的输出结果:
!Multiple row subquery多行子查询示例输出
3. 相关子查询
相关子查询是一种使用外部查询值的子查询。因此,对于来自外部查询的每一行值,子查询都会重复执行一次。
示例:
Select * from Products Where ProductID IN (Select ProductID from OrderDetails where OrderID =10255 OR OrderID=10256)
Order by ProductID
上述相关查询的输出结果:
!Correlated subquery 相关子查询输出
4. 嵌套子查询
当子查询内部存在 SQL SELECT 查询时,我们可以将其称为嵌套子查询。这意味着我们在查询中套用了查询,层层深入以获取所需的数据。