使用 EXISTS 的子查询

使用 EXISTS 关键字引入子查询后,子查询的作用就相当于进行存在测试。外部查询的 WHERE 子句测试子查询返回的行是否存在。子查询实际上不产生任何数据,它只返回 TRUE 或 FALSE 值。

使用 EXISTS 引入的子查询的语法如下:

WHERE [NOT] EXISTS (subquery)

以下查询将查找 Wheels 子类别中所有产品的名称:

USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE EXISTS
    (SELECT * 
     FROM Production.ProductSubcategory
     WHERE ProductSubcategoryID = 
            Production.Product.ProductSubcategoryID
        AND Name = 'Wheels')

下面是结果集:

Name
--------------------------------------------------
LL Mountain Front Wheel
ML Mountain Front Wheel
HL Mountain Front Wheel
LL Road Front Wheel
ML Road Front Wheel
HL Road Front Wheel
Touring Front Wheel
LL Mountain Rear Wheel
ML Mountain Rear Wheel
HL Mountain Rear Wheel
LL Road Rear Wheel
ML Road Rear Wheel
HL Road Rear Wheel
Touring Rear Wheel

(14 row(s) affected)

若要了解此查询的结果,请依次考虑每件产品的名称。此值是否使子查询至少返回一行?换句话说,查询是否使存在测试的计算结果为 TRUE?

注意,使用 EXISTS 引入的子查询在下列方面与其他子查询略有不同:

  • EXISTS 关键字前面没有列名、常量或其他表达式。

  • 由 EXISTS 引入的子查询的选择列表通常几乎都是由星号 (*) 组成。由于只是测试是否存在符合子查询中指定条件的行,因此不必列出列名。

由于通常没有备选的、无子查询的表示法,因此 EXISTS 关键字很重要。尽管一些使用 EXISTS 创建的查询不能以任何其他方法表示,但许多查询都可以使用 IN 或者由 ANY 或 ALL 修改的比较运算符来获取类似结果。

例如,可以使用 IN 表示上述查询:

USE AdventureWorks2008R2;
GO
SELECT Name
FROM Production.Product
WHERE ProductSubcategoryID IN
    (SELECT ProductSubcategoryID
     FROM Production.ProductSubcategory
     WHERE Name = 'Wheels')