SQL子查询


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

SQL子查询介绍

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

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

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

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

1
2
3
4
SELECT DISTINCT
reportsto
FROM
employees

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

1
2
3
4
5
6
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位于同一城市的所有客户:

1
2
3
4
5
6
7
8
9
10
11
12
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选择订单:

1
2
3
4
5
6
7
8
9
10
11
12
SELECT
orderid, customerid, shipname
FROM
orders_test
WHERE
customerid IN (
SELECT
customerid
FROM
customers
WHERE
country = 'USA');

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

1
2
3
4
5
6
7
8
9
10
11
12
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%:

1
2
3
4
5
6
7
8
9
10
11
UPDATE products
SET
unitprice = unitprice * 1.05
WHERE
productid IN (
SELECT
productid
FROM
suppliers
WHERE
supplierid = 15);

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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运算符组合时,可用于测试行是否存在。


原文链接:https://codingdict.com/