MySQL(七)---子查询(IN)

本文详细介绍如何使用SQL子查询进行数据筛选和计算。通过实例演示了如何利用子查询获取特定产品订单的客户信息,并展示了如何创建计算字段以统计每位客户的订单数量。

子查询(IN)

子查询(subquery), 即嵌套在其他查询中的查询。

本文采用了书中的数据库来介绍。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

订单存储在两个表中。对于包含订单号、客户ID、 订单日期的每个订单,orders表存储一行。各订单的物品存储在相关的 orderitems表中。orders表不存储客户信息。它只存储客户的ID。实际的客户信息存储在customers表中。

用子查询进行过滤

现在,假如需要列出订购物品TNT2的所有客户,应该怎样检索?下面列出具体的步骤。

  1. 检索包含物品TNT2的所有订单的编号。

    SELECT order_num FROM orderitems WHERE prod_id ='TNT2';
    
  2. 检索具有前一步骤列出的订单编号的所有客户的ID。

    SELECT cust_id FROM orders WHERE order_num IN  (20005,20007);
    
  3. 检索前一步骤返回的所有客户ID的客户信息

    SELECT * FROM customers WHERE cust_id IN  (10001,10004);
    

上述每个步骤都可以单独作为一个查询来执行。可以把一条SELECT 语句返回的结果用于另一条SELECT语句的WHERE子句。也可以使用子查询来把3个查询组合成一条语句。

子查询语法

SELECT * FROM 表名1 WHERE 列名1 IN (SELECT 列名2 FROM 表名2)
SELECT * 
FROM customers 
WHERE cust_id IN  (
	SELECT cust_id FROM orders WHERE order_num IN  
    (SELECT order_num FROM orderitems WHERE prod_id ='TNT2')
);

作为计算字段使用子查询

使用子查询的另一方法是创建计算字段。

假如需要显示customers表中每个客户的订单总数。订单与相应的客户ID存储在orders表中。

为了执行这个操作,遵循下面的步骤。

  1. 从customers表中检索客户列表。
  2. 对于检索出的每个客户,统计其在orders表中的订单数目。
SELECT cust_name,cust_state,
(SELECT COUNT(*) FROM orders WHERE 
orders.cust_id=customers.cust_id) AS orders
FROM customers; 
### MySQL 子查询的使用方法与示例 #### 一、子查询的基本定义 子查询是指在一个SQL语句中嵌套另一个查询语句的技术。它允许将一个查询的结果作为另一个查询的输入,从而实现更加灵活和复杂的查询需求[^3]。 #### 二、子查询的分类 根据功能和用途的不同,MySQL中的子查询主要分为以下几类: 1. **标量子查询** 标量子查询返回单个值,通常用于替换某个字段或表达式的值。例如,在WHERE子句中可以直接引用标量子查询的结果。 2. **多行子查询** 多行子查询返回多个值,通常配合IN、ANY、ALL等关键字一起使用。这类子查询适用于处理集合型的数据匹配问题[^4]。 3. **多列子查询** 当子查询返回两个或更多列时,则被称为多列子查询。此类查询主要用于涉及多字段比较的操作场景。 4. **相关子查询** 相关子查询的特点在于它的执行依赖于外部查询传递过来的具体记录信息。这意味着对于每一条外层查询的数据行,都需要重新运行一遍内层的相关子查询逻辑[^5]。 5. **非相关子查询** 非相关子查询独立完成自身的运算过程后再将其结果提供给上一层级调用者使用;也就是说在整个过程中仅需计算一次即可满足后续所有的参照请求。 #### 三、实际应用案例分析 ##### 示例一:查找工资高于平均薪资水平的所有员工姓名 ```sql SELECT name FROM employees WHERE salary > (SELECT AVG(salary) FROM employees); ``` 此段代码展示了如何利用标量形式的子查询来获取超过公司整体平均水平报酬额人员名单的情况[^1]。 ##### 示例二:找出部门编号为'01'且职位等级最高的雇员ID列表 ```sql SELECT emp_id FROM employee WHERE dept_no='01' AND job_level=(SELECT MAX(job_level) FROM employee WHERE dept_no='01'); ``` 这里运用到了单行比较操作符等于号以及最大函数MAX()共同构建而成的一个典型例子。 ##### 示例三:展示那些至少拥有一名下属经理级别的职员详情资料 ```sql SELECT * FROM staff s1 WHERE EXISTS ( SELECT 1 FROM staff s2 WHERE s2.manager_id=s1.staff_id ); ``` 上述片段体现了存在性检测EXISTS关键词搭配关联性质询结构组合起来解决问题的方法论思路。 --- #### 四、性能考量因素 尽管子查询提供了极大的灵活性,但在某些情况下可能会带来性能瓶颈。因此,在设计查询方案时应充分考虑以下几个方面的影响: - 尽可能减少不必要的重复扫描动作; - 对频繁访问的关键路径索引加以优化设置; - 利用临时表或者视图预先存储中间状态降低实时负载压力等等措施均有助于提升最终效果表现[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值