首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
第4章 数据更新
4-1 数据的插入(INSERT语句的使用方法)
什么是INSERT
INSERT语句的基本语法
列清单的省略
插入NULL
插入默认值
从其他表中复制数据
4-2 数据的删除(DELETE语句的使用方法)
DROP TABLE语句和DELETE语句
DELETE语句的基本语法
指定删除对象的DELETE语句(搜索型DELETE)
4-3 数据的更新(UPDATE语句的使用方法)
UPDATE语句的基本语法
指定条件的UPDATE语句(搜索型UPDATE)
使用NULL进行更新
多列更新
4-4 事务
什么是事务
创建事务
ACID特性
第5章 复杂查询
5-1 视图
视图和表
创建视图的方法
视图的限制① ——定义视图时不能使用ORDER BY子句
视图的限制② ——对视图进行更新
删除视图
5-2 子查询
子查询和视图
子查询的名称
标量子查询
标量子查询的书写位置
使用标量子查询时的注意事项
5-3 关联子查询
普通的子查询和关联子查询的区别
关联子查询也是用来对集合进行切分的
结合条件一定要写在子查询中
第6章 函数、谓词、CASE表达式
6-1 各种各样的函数
函数的种类
算术函数
字符串函数
日期函数
转换函数
6-2 谓词
什么是谓词
LIKE谓词——字符串的部分一致查询
BETWEEN谓词——范围查询
IS NULL、IS NOT NULL——判断是否为NULL
IN谓词——OR的简便用法
使用子查询作为IN谓词的参数
EXIST谓词
6-3 CASE表达式
什么是CASE表达式
CASE表达式的语法
CASE表达式的使用方法
第7章 集合运算
7-1 表的加减法
什么是集合运算
表的加法——UNION
集合运算的注意事项
包含重复行的集合运算——ALL选项
选取表中公共部分——INTERSECT
记录的减法——EXCEPT
7-2 联结(以列为单位对表进行联结)
什么是联结
内联结——INNER JOIN
外联结——OUTER JOIN
3张以上的表的联结
交叉联结——CROSS JOIN
联结的特定语法和过时语法
当前位置:
首页>>
技术小册>>
SQL基础教程(中)
小册名称:SQL基础教程(中)
### 5-2 子查询 在SQL的广阔天地中,子查询(Subquery)是一个强大而灵活的工具,它允许我们在一个查询内部嵌套另一个查询。这种结构不仅丰富了SQL的表达能力,还使得解决复杂数据检索问题变得更加直观和高效。本章将深入探讨子查询的基本概念、类型、应用场景以及最佳实践,帮助读者掌握这一关键技术。 #### 5.2.1 子查询基础 **定义**:子查询,顾名思义,就是嵌套在其他查询中的查询。它可以出现在SELECT、FROM、WHERE、HAVING等子句中,作为条件表达式或数据源的一部分。子查询的结果通常是一个值(标量子查询)、一行多列(行子查询)、或多行多列(表子查询),具体取决于其使用上下文。 **语法结构**: ```sql SELECT column_name(s) FROM table_name WHERE column_name OPERATOR (SELECT column_name(s) FROM table_name WHERE condition); ``` 这里,外层查询根据内层(子查询)返回的结果来过滤或选择数据。 #### 5.2.2 子查询的类型 根据子查询返回的结果类型及其在查询中的位置,我们可以将子查询分为以下几类: 1. **标量子查询**:返回单一值的子查询,常用于比较操作。 ```sql SELECT * FROM Employees WHERE Salary > (SELECT AVG(Salary) FROM Employees); ``` 此例中,子查询计算了所有员工的平均薪资,外层查询则选出了薪资高于平均值的员工。 2. **行子查询**:返回一行多列的子查询,常用于行级别的比较。 ```sql SELECT * FROM Orders WHERE (OrderID, OrderDate) = (SELECT MAX(OrderID), MAX(OrderDate) FROM Orders); ``` 这里,子查询找出了订单ID和订单日期都最大的那一行,外层查询则基于这一条件选择记录。 3. **表子查询**:返回多行多列的子查询,结果集可以视为一个临时表,用于FROM子句或作为其他查询的数据源。 ```sql SELECT * FROM (SELECT OrderID, SUM(Quantity) AS TotalQuantity FROM OrderDetails GROUP BY OrderID) AS OrderSummary WHERE TotalQuantity > 100; ``` 此例中,子查询首先计算了每个订单的总数量,然后外层查询从这个临时表(OrderSummary)中选出了总数量大于100的订单。 4. **关联子查询**(或称为相关子查询):在子查询中引用外层查询的列。这种子查询对于每一行外层查询的结果都会重新执行一次。 ```sql SELECT EmployeeID, Name, Salary FROM Employees E1 WHERE Salary > (SELECT AVG(Salary) FROM Employees E2 WHERE E2.DepartmentID = E1.DepartmentID); ``` 此查询找出了每个部门薪资高于该部门平均薪资的员工。 #### 5.2.3 子查询的应用场景 1. **数据过滤**:如上例所示,子查询常用于WHERE子句中以过滤数据。 2. **计算字段**:在SELECT列表中,子查询可以作为计算字段的一部分,用于动态计算每行的值。 3. **数据聚合与分组**:在GROUP BY或HAVING子句中使用子查询,可以对分组后的数据进行进一步的条件筛选或计算。 4. **存在性检查**:使用EXISTS关键字结合子查询,可以检查是否存在满足特定条件的记录。 ```sql SELECT * FROM Employees WHERE EXISTS (SELECT 1 FROM Orders WHERE Orders.EmployeeID = Employees.EmployeeID); ``` 此查询找出了至少有一个订单记录的员工。 5. **数据插入、更新、删除**:在INSERT、UPDATE、DELETE语句中,子查询可用于指定要插入的数据、更新的条件或删除的目标行。 #### 5.2.4 最佳实践与注意事项 1. **性能优化**:子查询,尤其是关联子查询,可能会因为对每一行外层查询结果都执行一次子查询而导致性能下降。考虑使用JOIN操作或临时表来优化性能。 2. **可读性**:虽然子查询提供了强大的灵活性,但过度使用或嵌套过深可能会降低SQL语句的可读性。在可能的情况下,使用清晰的JOIN语句或临时表来替代复杂的子查询。 3. **避免不必要的子查询**:在可以使用直接条件表达式或聚合函数解决的情况下,尽量避免使用子查询。 4. **注意子查询的返回类型**:确保子查询的返回类型与外层查询的期望类型相匹配,以避免类型不匹配错误。 5. **使用WITH子句(公用表表达式CTE)**:对于复杂的子查询,特别是那些需要被多次引用的,考虑使用WITH子句来定义公用表表达式,以提高可读性和可维护性。 #### 结语 子查询是SQL中不可或缺的一部分,它极大地扩展了SQL的查询能力,使得我们能够以更加灵活和强大的方式处理复杂的数据检索问题。通过掌握子查询的基本概念、类型、应用场景以及最佳实践,读者将能够更有效地利用SQL解决各种数据处理挑战。希望本章内容能为读者在SQL学习之路上提供有力的支持。
上一篇:
删除视图
下一篇:
子查询和视图
该分类下的相关小册推荐:
SQL基础教程(上)
SQL基础教程(下)
高性能的Postgres SQL
PostgreSQL入门教程