SQL子查询完全指南:SQL Ultimate Course查询嵌套技巧

📅 2026/7/4 7:00:44 👁️ 阅读次数 📝 编程学习
SQL子查询完全指南:SQL Ultimate Course查询嵌套技巧

SQL子查询完全指南:SQL Ultimate Course查询嵌套技巧

【免费下载链接】sql-ultimate-courseThe most comprehensive SQL guide from a real-world expert! Learn everything from basics to advanced queries, optimizations, and real-world SQL项目地址: https://gitcode.com/gh_mirrors/sq/sql-ultimate-course

SQL子查询是SQL查询中强大而灵活的工具,它允许你在一个查询中嵌套另一个查询,从而解决复杂的数据检索问题。本指南将带你从基础到高级,掌握SQL子查询的核心技巧和实际应用场景,让你的SQL查询能力提升到新高度。

什么是SQL子查询?

子查询(Subquery)是嵌套在另一个SQL查询中的查询语句,也称为内部查询。外部查询可以使用子查询的结果来进一步过滤、计算或处理数据。子查询就像一个数据过滤器或计算器,帮助你从数据库中提取更精确的信息。

子查询的主要优势在于:

  • 可以将复杂问题分解为简单的逻辑步骤
  • 减少多步查询的需要
  • 提高代码可读性和维护性
  • 实现JOIN难以完成的复杂逻辑

图:SalesDB数据模型展示了本文示例中使用的表结构和关系,包括Products、Orders、Customers和Employees表。

子查询的基本类型

根据返回结果的不同,子查询可以分为三种基本类型:

1. 标量子查询(Scalar Subquery)

返回单个值的子查询,通常用于SELECT、WHERE或HAVING子句中。

SELECT AVG(Sales) FROM Sales.Orders;

2. 行子查询(Row Subquery)

返回单行多列的结果,通常用于与单行比较。

SELECT CustomerID FROM Sales.Orders;

3. 表子查询(Table Subquery)

返回多行多列的结果集,通常用于FROM子句中作为临时表。

SELECT OrderID, OrderDate FROM Sales.Orders;

子查询在不同子句中的应用

FROM子句中的子查询

将子查询结果作为临时表使用,也称为派生表(Derived Table)。

示例:查找价格高于平均价格的产品

SELECT * FROM ( SELECT ProductID, Price, AVG(Price) OVER () AS AvgPrice FROM Sales.Products ) AS t WHERE Price > AvgPrice;

任务:客户销售排名

使用子查询结合窗口函数对客户销售总额进行排名:

SELECT *, RANK() OVER (ORDER BY TotalSales DESC) AS CustomerRank FROM ( SELECT CustomerID, SUM(Sales) AS TotalSales FROM Sales.Orders GROUP BY CustomerID ) AS t;

SELECT子句中的子查询

在SELECT列表中使用子查询,可以为每一行返回一个计算值。

示例:显示产品信息及总订单数

SELECT ProductID, Product, Price, (SELECT COUNT(*) FROM Sales.Orders) AS TotalOrders FROM Sales.Products;

JOIN子句中的子查询

子查询可以作为JOIN操作的一部分,创建更灵活的连接条件。

示例:客户及其总销售额

SELECT c.*, t.TotalSales FROM Sales.Customers AS c LEFT JOIN ( SELECT CustomerID, SUM(Sales) AS TotalSales FROM Sales.Orders GROUP BY CustomerID ) AS t ON c.CustomerID = t.CustomerID;

子查询与运算符的结合使用

比较运算符中的子查询

使用比较运算符(=, >, <, >=, <=, <>)结合子查询,进行值比较。

示例:查找价格高于平均价格的产品

SELECT ProductID, Price, (SELECT AVG(Price) FROM Sales.Products) AS AvgPrice FROM Sales.Products WHERE Price > (SELECT AVG(Price) FROM Sales.Products);

IN运算符中的子查询

IN运算符允许你在WHERE子句中指定多个值,非常适合与返回多个结果的子查询一起使用。

示例:查找德国客户的订单

SELECT * FROM Sales.Orders WHERE CustomerID IN ( SELECT CustomerID FROM Sales.Customers WHERE Country = 'Germany' );

使用NOT IN可以排除特定条件的结果:

SELECT * FROM Sales.Orders WHERE CustomerID NOT IN ( SELECT CustomerID FROM Sales.Customers WHERE Country = 'Germany' );

ANY/SOME运算符中的子查询

ANY运算符允许你将一个值与子查询返回的多个值进行比较。

示例:查找薪资高于任何男性员工的女性员工

SELECT EmployeeID, FirstName, Salary FROM Sales.Employees WHERE Gender = 'F' AND Salary > ANY ( SELECT Salary FROM Sales.Employees WHERE Gender = 'M' );

高级子查询技术

相关子查询(Correlated Subquery)

相关子查询是引用外部查询列的子查询,它会为外部查询的每一行执行一次。

示例:显示客户详情及各自的订单总数

SELECT *, (SELECT COUNT(*) FROM Sales.Orders o WHERE o.CustomerID = c.CustomerID) AS TotalSales FROM Sales.Customers AS c;

EXISTS运算符

EXISTS运算符用于检查子查询是否返回任何行,返回布尔值(TRUE或FALSE)。

示例:检查是否存在德国客户的订单

SELECT * FROM Sales.Orders AS o WHERE EXISTS ( SELECT 1 FROM Sales.Customers AS c WHERE Country = 'Germany' AND o.CustomerID = c.CustomerID );

使用NOT EXISTS可以检查不存在的情况:

SELECT * FROM Sales.Orders AS o WHERE NOT EXISTS ( SELECT 1 FROM Sales.Customers AS c WHERE Country = 'Germany' AND o.CustomerID = c.CustomerID );

子查询最佳实践

  1. 保持简洁:每个子查询只做一件事,避免过于复杂的嵌套
  2. 使用别名:为子查询结果集指定有意义的别名,提高可读性
  3. 注意性能:相关子查询可能导致性能问题,考虑使用JOIN替代
  4. 测试独立运行:先单独测试子查询,确保返回预期结果
  5. 考虑替代方案:某些情况下,JOIN或窗口函数可能比子查询更高效

总结

SQL子查询是处理复杂数据检索的强大工具,从简单的标量查询到高级的相关子查询,掌握这些技巧将极大提升你的SQL查询能力。通过本文介绍的各种子查询类型和应用场景,你可以开始在实际项目中灵活运用子查询解决复杂问题。

完整的子查询示例代码可以在项目的scripts/18_Subqueries.sql文件中找到,包含了从基础到高级的各种子查询技术实现。

无论你是SQL初学者还是有经验的开发者,掌握子查询都是提升SQL技能的关键一步。通过不断练习和应用这些技巧,你将能够编写更高效、更优雅的SQL查询。

要开始使用本项目中的SQL子查询示例,你可以克隆仓库:

git clone https://gitcode.com/gh_mirrors/sq/sql-ultimate-course

【免费下载链接】sql-ultimate-courseThe most comprehensive SQL guide from a real-world expert! Learn everything from basics to advanced queries, optimizations, and real-world SQL项目地址: https://gitcode.com/gh_mirrors/sq/sql-ultimate-course

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考