MySQL 中 delete 语句的子查询限制

本文介绍了在MySQL中遇到特定删除语句错误的情况,并提供了有效的解决办法。文章详细解释了如何避免因目标表同时出现在FROM子句和DELETE语句中而导致的错误,并展示了如何正确地使用子查询和别名来解决问题。

场景一


delete from student where id = (select max(id) from student);

[Err] 1093 - You can't specify target table 'student' for update in FROM clause

描述: 如果子查询的 from 子句和更新、删除对象使用同一张表,会出现上述错误。

解决方法: 通过给 from 子句中的结果集起别名。


delete from student where id = (select n.max_id from (select max(id) as max_id from student) as n);

上述情况对于 in 子句也适用


delete from student where id in (select id from student where id > 30);

[Err] 1093 - You can't specify target table 'student' for update in FROM clause

解决方法同上:


delete from student where id in (select n.id from (select id from student where id > 30) as n);

场景二


delete from student m where m.id = 1;

[Err] 1064 - You have an error in your SQL syntax;

描述: delete from table 这样的句子中 table 不能使用别名。

解决方法:去掉别名:


delete from student where id = 1;
Whatever is worth doing is worth doing well.
### MySQL 子查询的定义和用法 #### 什么是子查询子查询是指在另一个 SQL 查询内部嵌套的查询语句。它通常出现在 `SELECT`、`INSERT`、`UPDATE` 或 `DELETE` 语句中,并且可以用于 `WHERE`、`FROM` 或 `HAVING` 子句中[^3]。子查询的执行顺序是由内到外,这意味着子查询会在其父查询之前被处理,其结果会被回传给父查询。 #### 子查询的语法结构 子查询的基本结构如下: ```sql SELECT column_name(s) FROM table_name WHERE column_name operator ( SELECT column_name FROM table_name WHERE condition ); ``` #### 子查询的类型 根据用途和位置的同,子查询可以分为以下几种类型: 1. **标量子查询**:返回单个值的子查询。 示例: ```sql SELECT employee_id, salary FROM employees WHERE salary > (SELECT AVG(salary) FROM employees); ``` 上述查询将返回所有工资高于平均工资的员工信息[^3]。 2. **列子查询**:返回一列值的子查询。 示例: ```sql SELECT product_name FROM products WHERE category_id IN (SELECT category_id FROM categories WHERE name = 'Electronics'); ``` 这里查询了属于“Electronics”类别的所有产品名称。 3. **行子查询**:返回一行或多行的子查询。 示例: ```sql SELECT customer_id, order_date FROM orders WHERE (customer_id, order_date) IN ( SELECT customer_id, MAX(order_date) FROM orders GROUP BY customer_id ); ``` 此查询找出每位客户的最近一次订单日期。 4. **子查询**:作为来源的子查询,通常用于 `FROM` 子句中。 示例: ```sql SELECT avg_salary, department_id FROM ( SELECT department_id, AVG(salary) AS avg_salary FROM employees GROUP BY department_id ) AS dept_avg; ``` 这段代码计算每个部门的平均工资并展示结果。 #### 使用 `WITH AS` 定义公用达式 为了提高复杂查询的可读性和性能,MySQL 支持通过 `WITH AS` 定义公用达式(CTE)。这种技术允许将复杂的子查询提取出来,赋予一个别名,并在主查询中多次引用[^2]。 示例: ```sql WITH top_customers AS ( SELECT customer_id, SUM(amount) AS total_spent FROM orders GROUP BY customer_id HAVING total_spent > 1000 ) SELECT c.customer_name, tc.total_spent FROM customers c JOIN top_customers tc ON c.id = tc.customer_id; ``` 上述代码首先定义了一个名为 `top_customers` 的 CTE,然后将其与主 `customers` 进行联结以获取高消费客户的信息。 #### 子查询中的注意事项 - 子查询必须用圆括号括起来。 - 如果子查询返回多行数据,则需要使用适合的操作符(如 `IN`、`ANY` 或 `ALL`)。 - 在某些情况下,MySQL 会忽略子查询中的列列内容,因此可以选择任意值(如 `SELECT *` 或 `SELECT 1`)[^1]。 #### 子查询的应用场景 子查询适用于多种场景,包括但限于: - 报统计:当需要从多个中汇总数据时。 - 数据筛选:基于子查询的结果进行进一步过滤。 - 数据关联:通过子查询实现跨联结。 - 复杂条件:构建复杂的逻辑判断条件。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值