6.1、子查询类型:
单行子查询、多行子查询、多列子查询、关联子查询、嵌套子查询
6.2、编写单行子查询: 不向外部SQL语句返回结果,或者值返回一行。
可放在where、having、from子句中。
6.2.1、where子句中一般使用“=”操作符,也可以使用<>、>、<、>=、<=等单行操作符。
6.2.2、在having子句中使用子查询; 可以基于子查询返回结果对行组进行过滤。
select product_id AVG(price) from products
group by product_id
having AVG(price) < (select MAX(AVG(price)) from products group by product_id )
order by product_id;
6.2.3、在from子句中使用子查询(内联视图)如:
在外部查询中从products表中检索product_id和price列,在子查询中检索一种产品已经被购买的次数:
SELECT prds.product_id , price , purchases_data.pri=product_count
FROM products prds , ( SELECT product_id , COUNT( product_id ) product_count
FROM purchases
GROUP BY product_id ) purchases_data
WHERE prds.product_id = purchases_data.product_id ;
6.2.4、可能遇到的错误;
1、单行子查询最多返回一行 2、子查询不能包含ORDER BY 子句
6.3、编写多行子查询:可以向外部的SQL语句返回一行或多行记录。
外部查询可以使用IN、 ANY 、ALL操作符
SELECT employee_id ,name FROM employees
WHERE salary < ANY ( SELECT low_salary FROM salary_grades )
6.4、编写多列子查询:
SELECT product_id ,product_type_id, name, price
FROM products
WHERE ( product_type_id, price ) IN
( SELECT product_type_id, MIN(price)
FROM products GROUP BY product_type_id );
6.5、编写关联子查询: 引用外部SQL语句中的一列或者多列。
关联子查询对于外部查询的每一行都会运行一次,和可以解决空值问题,
而非关联子查询只在运行外部查询之前运行一次
6.5.1、EXISTS操作符用于检查子查询返回的行的存在性。
虽然它也可以用在非关联子查询,但是EXISTS通常用于关联子查询。
由于EXISTS只检查子查询返回行的存在性,因此子查询不必返回一列,
可以只返回一个常量;这样可以提高查询性能。
例如:SELECT employee_id , name FROM employees outer
Where EXISTS ( SELECT 1 FROM employees inner
WHERE inner.manager_id = outer.employee_id );
6.5.2、EXISTS 与IN 不同:EXISTS只检查行的存在性,而IN则要检查实际值的存在性。
1、通常来讲,EXISTS的性能高于IN,因此尽可能使用EXISTS。
2、当一个值列表包含一个空值时NOT EXISTS返回TRUE,而 NOT IN则返回FALSE。
6.6、编写嵌套子查询:
在子查询内部可以嵌套其他子查询,嵌套层次做多为255;但编程时应尽量避免使用。
6.7、编写包含子查询的UPDATE 和DELETE 语句;
UPDATE employees
SET salary = ( SELECT AVG(high_salary) FROM salary_grades )
WHERE employee_id = 4;
删除工资高于从子查询中返回的高工资级别平均值的员工记录:
DELETE FROM emplyees
WHERE salary > ( SELECT AVG(high_salary) FROM salary_grades )