目录
- 介绍
- 示例
- 总结
- 引用
- 数据库脚本下载
1. 介绍
高级子查询在 T-SQL 中提供了更复杂的查询能力,如返回前一个或后一个记录、连续聚合等。本文将介绍这些高级子查询的概念和应用。
2. 示例
- 返回前一个或后一个记录
示例:返回下一个小于当前订单号的最大值
SELECT
orderid, orderdate, empid, custid,
( SELECT MAX(O2.orderid)
FROM Sales.Orders O2
WHERE O2.orderid < O1.orderid
) AS PrevOrderid
FROM Sales.Orders O1;
结果输出 830行:
示例:返回下一个大于当前订单号的最小值
SELECT
orderid, orderdate, empid, custid,
( SELECT MIN(O2.orderid)
FROM Sales.Orders O2
WHERE O2.orderid > O1.orderid
) AS NextOrderid
FROM Sales.Orders O1;
结果输出 830行:
- 连续聚合
连续聚合是一种累积数据(通常是按时间顺序)执行的聚合。
示例:返回每年的订单年份/订货量,以及连续几年的总订货量
SELECT
orderyear, qty,
( SELECT SUM(qty)
FROM Sales.OrderTotalsByYear O2
WHERE O1.orderyear >= O2.orderyear
) AS RunQty
FROM Sales.OrderTotalsByYear AS O1;
- 行为不当的子查询
示例:IN 谓词使用三值逻辑
SELECT custid, companyname
FROM Sales.Customers C
WHERE custid NOT IN (
SELECT O.custid FROM Sales.Orders O
);
**结果输出 **
-- IN 谓词 使用三值谓语逻辑
-- NULL 问题
-- 当子查询出现 NULL 值,但没有考虑三值逻辑时,会导致子查询出现问题
-- ** 当orders 表中的custid 出现null值时,返回空集。因为 IN 谓语和 NULL 比较返回 UNknown
-- Where 会过滤 Unknown
解决方案:排除 NULL 值
SELECT custid, companyname FROM Sales.Customers C
WHERE EXISTS (
SELECT O.custid
FROM Sales.Orders O
where O.custid is not null
);
结果输出 92行:
解释: 当子查询出现 NULL 值时,需要显式排除这些值以避免查询问题。
3. 总结
高级子查询提供了更复杂和强大的查询能力,如返回前一个或后一个记录、连续聚合等。通过理解和应用这些高级子查询,我们可以编写更灵活和高效的 SQL 查询。
4. 引用
- Microsoft SQL Server 文档:https://docs.microsoft.com/en-us/sql/sql-server/