首页
技术小册
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基础教程(中)
### 章节:普通的子查询和关联子查询的区别 在SQL(Structured Query Language)的世界里,子查询作为一种强大的查询工具,广泛应用于数据检索、数据分析和复杂逻辑的实现中。子查询可以嵌套在SELECT、INSERT、UPDATE或DELETE语句中,用于提供数据过滤、计算或作为临时表使用。根据子查询与外层查询的关系和执行方式的不同,子查询可以分为普通子查询(也称为非关联子查询)和关联子查询(也称为相关子查询)两大类。本章节将深入探讨这两种子查询的区别,包括它们的定义、应用场景、性能考量以及示例解析。 #### 一、普通子查询(非关联子查询) **定义**: 普通子查询,也称为非关联子查询,是指子查询的执行不依赖于外层查询的当前行数据。换句话说,子查询在执行时,其内部使用的条件和参数已经确定,不会随着外层查询的逐行处理而改变。因此,非关联子查询可以被视为一个独立的查询,其执行结果在外层查询执行前就已经确定。 **应用场景**: - **数据过滤**:用于在外层查询的WHERE子句中过滤数据,例如查询薪资高于公司平均水平的员工。 - **计算字段**:在SELECT子句中使用子查询作为计算字段的一部分,如计算每个员工薪资与平均薪资的差值。 - **存在性检查**:使用EXISTS或NOT EXISTS关键字判断子查询是否返回结果,常用于检查某条件是否满足。 **性能考量**: 由于非关联子查询的执行不依赖于外层查询的当前行,因此其执行计划通常较为简单且易于优化。然而,如果子查询本身涉及大量数据或复杂逻辑,仍可能对查询性能产生较大影响。 **示例**: ```sql -- 查询薪资高于公司平均水平的员工 SELECT employee_id, name, salary FROM employees WHERE salary > ( SELECT AVG(salary) FROM employees ); ``` 在此示例中,子查询`(SELECT AVG(salary) FROM employees)`计算了公司所有员工的平均薪资,这个平均值是固定的,不会因外层查询处理的不同员工而改变。 #### 二、关联子查询(相关子查询) **定义**: 关联子查询,也称为相关子查询,其执行依赖于外层查询的当前行数据。在关联子查询中,子查询内部可能会引用外层查询的列,因此子查询的执行结果会随着外层查询的逐行处理而动态变化。 **应用场景**: - **逐行比较**:用于在外层查询的每一行上执行特定的逻辑比较,如查询没有订单的客户。 - **动态计算**:在SELECT子句中使用关联子查询进行动态计算,如计算每个员工在部门内的薪资排名。 - **分组内的比较**:在分组查询中,利用关联子查询实现分组内的复杂比较逻辑。 **性能考量**: 关联子查询因其动态性,可能导致查询性能下降。对于每一行外层查询的结果,都需要重新执行子查询,这可能导致大量的重复计算。在某些情况下,可以通过重写查询为JOIN或使用窗口函数(如果数据库支持)来提高性能。 **示例**: ```sql -- 查询薪资高于部门平均薪资的员工 SELECT employee_id, name, salary, department_id FROM employees e1 WHERE salary > ( SELECT AVG(salary) FROM employees e2 WHERE e2.department_id = e1.department_id ); ``` 在此示例中,子查询`(SELECT AVG(salary) FROM employees e2 WHERE e2.department_id = e1.department_id)`计算了与外层查询当前行相同部门内员工的平均薪资。由于子查询中引用了外层查询的`department_id`列,因此子查询的执行结果会随外层查询的逐行处理而变化。 #### 三、区别总结 - **执行依赖性**:普通子查询不依赖于外层查询的当前行数据,而关联子查询则依赖于外层查询的当前行数据。 - **执行时机**:普通子查询在外层查询执行前就已经完成计算,而关联子查询在外层查询的每一行上都会重新执行。 - **应用场景**:普通子查询更适用于全局性的数据过滤和计算,而关联子查询则适用于需要逐行比较或动态计算的场景。 - **性能影响**:关联子查询可能因大量重复计算而导致性能下降,而普通子查询则相对更易于优化。 #### 四、最佳实践 - **考虑性能**:在编写包含子查询的查询时,应优先考虑其对性能的影响。对于可能涉及大量数据或复杂逻辑的查询,考虑使用JOIN或其他优化手段替代子查询。 - **避免不必要的复杂性**:尽量保持查询的简洁性,避免在不需要时使用关联子查询。有时候,通过重新组织查询逻辑或使用窗口函数等高级特性,可以达到更好的性能和可读性。 - **测试与验证**:对于复杂的查询,尤其是包含子查询的查询,应通过实际的测试数据和性能分析工具来验证其效率和准确性。 综上所述,普通子查询和关联子查询在SQL查询中扮演着不同的角色,它们之间的选择应基于具体的查询需求、数据特性和性能考量。通过深入理解这两种子查询的区别和应用场景,我们可以更加灵活地运用SQL语言,编写出高效、准确的查询语句。
上一篇:
5-3 关联子查询
下一篇:
关联子查询也是用来对集合进行切分的
该分类下的相关小册推荐:
SQL基础教程(上)
PostgreSQL入门教程
高性能的Postgres SQL
SQL基础教程(下)