MySQL子查询定义
MySQL子查询(也称作内部查询或嵌套查询)是在一个主查询(外部查询)内部执行的查询语句。子查询独立执行,其结果可以被主查询用来进一步过滤、比较或者计算。子查询能够提高查询的灵活性,使得我们可以基于一个查询结果来构造另一个查询,从而实现复杂的数据检索需求。
使用方式
1. 标量子查询
- 定义:返回单一值的子查询,通常用于比较运算符中。
- 语法示例:
SELECT column_name FROM table_name WHERE column_name operator (SELECT scalar_value FROM another_table WHERE condition);
- 实际案例:找出价格高于最便宜商品价格10%的所有商品。
SELECT product_name, price FROM products WHERE price > (SELECT price * 1.1 FROM products ORDER BY price LIMIT 1);
2. 列子查询
- 定义:返回一列或多行单列值的子查询,常与
IN
、ANY/SOME
、ALL
配合。 - 语法示例:
SELECT column_name FROM table_name WHERE column_name operator ANY|SOME|(ALL) (SELECT column_name FROM another_table WHERE condition);
- 实际案例:找出属于销售量最高类别的所有商品。
SELECT product_name FROM products WHERE category_id IN ( SELECT category_id FROM sales GROUP BY category_id ORDER BY SUM(quantity) DESC LIMIT 1 );
当然,让我们详细探讨 IN
、ANY/SOME
、ALL
、和 EXISTS
在列子查询中的使用方式及其含义,通过具体示例来理解它们的应用。
1. IN操作符
IN
用来测试某个值是否在子查询返回的一列值中。如果匹配到任何值,则条件为真。
示例:找出所有销售了"Electronics"类别产品的订单。
SELECT order_id
FROM orders o
WHERE o.product_id IN (
SELECT product_id
FROM products
WHERE category = 'Electronics'
);
2. ANY/SOME操作符
ANY
和 SOME
是同义词,在比较表达式中与子查询结合使用时,表示只要子查询中有至少一个值满足条件即可。
示例:找出所有订单金额大于产品表中任意一个产品平均售价的订单。
SELECT order_id
FROM orders
WHERE total_amount > ANY (
SELECT AVG(price)
FROM products
GROUP BY product_category
);
3. ALL操作符
ALL
在比较表达式中与子查询结合使用,要求与子查询返回的所有值都满足比较条件。
示例:找出所有订单金额大于产品表中所有产品平均售价的客户ID。
SELECT customer_id
FROM orders
WHERE total_amount > ALL (
SELECT AVG(price)
FROM products
);
注意:实际上,这个例子可能不太合理,因为一个订单的总金额很难大于所有产品的平均价格之和,这里仅为了演示 ALL
的用法。
4. EXISTS操作符
EXISTS
用于检查子查询是否返回行。如果子查询至少返回一行数据,则 EXISTS
的结果为真,它不关心子查询返回的具体数据。
示例:找出有对应销售记录的员工ID。
SELECT employee_id
FROM employees e
WHERE EXISTS (
SELECT 1
FROM sales s
WHERE s.employee_id = e.employee_id
);
在这个例子中,子查询不返回具体值,仅用于检查是否有匹配的行存在。
3. 表子查询(FROM子句中的子查询)
- 定义:子查询返回一组行,作为外部查询的临时表。
- 语法示例:
SELECT ... FROM (SELECT column_list FROM table_name WHERE condition) AS alias_name WHERE ...;
- 实际案例:找出每个员工的最高销售额。
SELECT e.employee_name, max_sales.max_sale_amount FROM employees e JOIN ( SELECT employee_id, MAX(total_sale_amount) AS max_sale_amount FROM sales GROUP BY employee_id ) max_sales ON e.employee_id = max_sales.employee_id;
注意事项
- 性能考虑:尽管子查询非常灵活,但复杂的子查询可能会降低查询性能。在某些情况下,使用JOIN或者EXISTS可能更为高效。
- 子查询的执行顺序:子查询会在主查询之前执行,且对于每个外层查询的行,子查询都会重新执行一次(除非是相关子查询)。
- 相关子查询:与外部查询的行相关的子查询,这类查询的执行计划和性能分析更为复杂,因为它依赖于外部查询的具体行值。
第5章 多表操作.pptx
https://www.alipan.com/s/ncMMHnK36jr
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。