关于关联子查询--correlated subquery

关联子查询在Oracle中是指嵌套子查询引用了来自父查询中任何层级的表格的列。每次处理父查询的一行时,都会评估一次子查询。它用于回答依赖于父查询每行处理值的多部分问题,例如找出薪水高于部门平均薪资的员工。子查询为每个部门计算平均工资,然后与父查询中的当前行进行比较,满足条件的行将被返回。

文档地址:http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries007.htm#sthref3193

 

Using Subqueries

 

    Oracle performs a correlatedsubquery when a nested subquery references a column from atable referred to a parent statement any number of levels above thesubquery. The parent statement can be a SELECT,UPDATE, or DELETE statement in which thesubquery is nested. A correlated subquery is evaluated once foreach row processed by the parent statement. Oracle resolvesunqualified columns in the subquery by looking in the tables namedin the subquery and then in the tables named in the parentstatement.

    Acorrelated subquery answers a multiple-part question whose answerdepends on the value in each row processed by the parent statement.For example, you can use a correlated subquery to determine whichemployees earn more than the average salaries for theirdepartments. In this case, the correlated subquery specificallycomputes the average salary for each department.

\
 
 

Using CorrelatedSubqueries: Examples The following examples show the generalsyntax of a correlated subquery:

SELECT select_list 
    FROM table1 t_alias1 
    WHERE expr operator 
        (SELECT column_list 
            FROM table2 t_alias2 
            WHERE t_alias1.column 
               operator t_alias2.column); 

UPDATE table1 t_alias1 
    SET column = 
        (SELECT expr 
            FROM table2 t_alias2 
            WHERE t_alias1.column = t_alias2.column); 

DELETE FROM table1 t_alias1 
    WHERE column operator 
        (SELECT expr 
            FROM table2 t_alias2 
            WHERE t_alias1.column = t_alias2.column); 

The following statement returns data about employees whosesalaries exceed their department average. The following statementassigns an alias to employees, the table containingthe salary information, and then uses the alias in a correlatedsubquery:

SELECT department_id, last_name, salary 
   FROM employees x 
   WHERE salary > (SELECT AVG(salary) 
      FROM employees 
      WHERE x.department_id = department_id) 
   ORDER BY department_id; 

For each row of the employees table, the parentquery uses the correlated subquery to compute the average salaryfor members of the same department. The correlated subqueryperforms the following steps for each row of theemployees table:---它的执行的步骤

  1. The department_id of the row is determined.

  2. The department_id is then used to evaluate theparent query.

  3. If the salary in that row is greater than the averagesalary of the departments of that row, then the row isreturned.--从此处看,父查询在子查询确定了AVG(salary)以后,每一次都要执行比较,如果满足条件,那么父查询会将此行返回。即查询中有多少行,那么父查询就要执行多少次条件比较。

The subquery is evaluated once for each row of theemployees table.

### 关联子查询的使用方法 关联子查询Correlated Subquery)是一种依赖于外部查询值的子查询,通常用于对每一行数据执行复杂的条件过滤或计算。与独立子查询不同,关联子查询不能单独运行,它必须引用外部查询中的字段,以便为每一行生成特定的结果。 在 PostgreSQL 中,关联子查询常用于 `WHERE` 子句或 `SELECT` 列表中,以实现基于外部查询字段的动态过滤或计算。例如,以下查询使用关联子查询查找薪资高于其部门平均薪资的员工: ```sql SELECT e.name, e.salary FROM employees e WHERE e.salary > ( SELECT AVG(e2.salary) FROM employees e2 WHERE e2.department_id = e.department_id ); ``` 在这个例子中,子查询 `(SELECT AVG(e2.salary) ...)` 依赖于外部查询中的 `e.department_id`,为每一行员工记录计算其所在部门的平均薪资,并进行比较[^3]。 ### 关联子查询的优化与注意事项 由于关联子查询在外部查询的每一行上都会执行一次,因此在大数据集上可能会影响性能。为避免性能瓶颈,可以考虑以下优化策略: - **使用索引**:在子查询中频繁使用的字段(如外键或常用过滤条件字段)上创建索引,可显著提升执行效率。 - **使用 EXISTS 替代 IN**:当只需要判断是否存在满足条件的记录时,`EXISTS` 通常比 `IN` 更高效,因为 `EXISTS` 在找到第一条匹配记录后即可停止搜索。 ```sql SELECT d.dept_name FROM departments d WHERE EXISTS ( SELECT 1 FROM employees e WHERE e.department_id = d.id ); ``` - **避免不必要的嵌套**:在某些情况下,可以通过 `JOIN` 操作替代关联子查询,以提高查询效率。例如,上述查询也可以使用 `INNER JOIN` 实现: ```sql SELECT DISTINCT d.dept_name FROM departments d INNER JOIN employees e ON d.id = e.department_id; ``` - **使用 CTE(Common Table Expressions)**:通过 `WITH` 子句定义的 CTE 可以将复杂的子查询逻辑拆分出来,提高代码可读性和维护性,同时也有助于优化器生成更高效的执行计划。 ```sql WITH department_avg_salary AS ( SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id ) SELECT e.name, e.salary FROM employees e INNER JOIN department_avg_salary das ON e.department_id = das.department_id WHERE e.salary > das.avg_salary; ``` 上述方法可以有效减少重复计算,提高查询效率[^1]。 ### 示例:使用关联子查询进行复杂过滤 以下示例展示如何使用关联子查询查找每个部门中薪资最高的员工: ```sql SELECT e.name, e.salary, e.department_id FROM employees e WHERE e.salary = ( SELECT MAX(e2.salary) FROM employees e2 WHERE e2.department_id = e.department_id ); ``` 该查询中,子查询 `(SELECT MAX(e2.salary) ...)` 为每个部门计算最高薪资,并与外部查询中的员工薪资进行比较,从而筛选出每个部门的最高薪员工。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值