SQL子查询

时间:2018-11-15 17:45:07  来源:igfitidea点击:

在本教程中,我们将学习SQL子查询,它是嵌套在另一个查询中以形成复杂查询的常规查询。

SQL子查询介绍

子查询是嵌套在另一个查询(如SELECT、UPDATE或DELETE语句)中的常规SELECT语句。

下图说明了子查询的概念:

子查询也称为内部选择或内部查询,而包含子查询的查询称为外部选择或外部查询。

在上图中,子查询返回一个由三行组成的结果集。

SELECT DISTINCT
    reportsto
FROM
    employees

将此结果集提取到外部查询的IN运算符。外部查询等同于:

SELECT 
    employeeid, firstname, lastname
FROM
    employees
WHERE
    employeeid IN (5 , 3, null);

它返回employees表中的所有经理。
在本例中,子查询的结果由外部查询使用。数据库引擎执行整个查询两次,一次用于子查询,一次用于外部查询。

子查询也可以嵌套在另一个子查询中。嵌套级别的数量取决于特定数据库产品的实现。例如,Microsoft SQL Server最多支持32个级嵌套。

SQL子查询示例

在以下示例中,我们将使用以下表:

customers – 存储客户主数据。
products – 存储产品主数据。
orders_test – 存储订单头数据,包括进行采购的客户。
orderdetails – 存储订单行项目数据。

子查询可以返回一行或多行。
当子查询返回一行时,可以在外部查询中使用比较运算符(如=、>、<、>=、<=和<>)将值与子查询返回的值进行比较。

例如,以下查询使用不等于(<>)运算符选择与客户id BSBEV位于同一城市的所有客户:

SELECT 
    customerid, companyname, city
FROM
    customers
WHERE
    customerid <> 'BSBEV'
        AND city = (SELECT 
            city
        FROM
            customers
        WHERE
            customerid = 'BSBEV')

首先,子查询返回客户BSBEV所在的城市,即London。然后,使用London向外部查询提供数据,以查找位于伦敦市的所有客户。

使用IN和NOT IN的SQL子查询示例

如果子查询返回包含多行的结果集,则可以在外部查询中使用In或NOT In运算符来检查值是否在子查询返回的结果集中。

例如,以下查询美国客户的所有订单,子查询选择美国客户的所有ID,外部查询使用这组ID选择订单:

SELECT 
    orderid, customerid, shipname
FROM
    orders_test
WHERE
    customerid IN (
        SELECT 
            customerid
        FROM
            customers
        WHERE
            country = 'USA');

您还可以使用NOT-IN运算符查询美国以外的所有订单,如下所示:

SELECT 
    orderid, customerid, shipname
FROM
    orders_test
WHERE
    customerid NOT IN (
        SELECT 
            customerid
        FROM
            customerS
        WHERE
            country = 'USA')

在UPDATE 语句中使用SQL子查询

子查询不仅嵌套在SELECT语句中,还可以嵌套在其他语句(如UPDATE和DELETE语句)中。

例如,下面的语句将supplierid为15的供应商提供的产品单价提高5%:

UPDATE products 
SET 
    unitprice = unitprice * 1.05
WHERE
    productid IN (
        SELECT 
            productid
        FROM
            suppliers
        WHERE
            supplierid = 15);

子查询选择supplierid为15的供应商提供的产品的所有id。然后,将id集提取到UDPATE语句中以更新单价。

SQL子查询作为表达式的示例

子查询可用于替换SQL语句中的表达式。

例如,下面的查询返回所有饮料产品的价格、产品的平均价格以及单价和平均价格之间的差异。

SELECT 
    productid,
    productname,
    (SELECT 
            AVG(unitprice)
     FROM
            products) AS 'average price',
          (unitprice - (
              SELECT  
                   AVG(unitprice)
              FROM
                   products)) AS diff
FROM
    products
WHERE
    categoryid = 1

带有EXISTS和NOT EXISTS运算符的SQL子查询

子查询与EXISTS和NOT EXISTS运算符组合时,可用于测试行是否存在。