返回单行子查询的更新语句返回多于一行
Posted
技术标签:
【中文标题】返回单行子查询的更新语句返回多于一行【英文标题】:Update statement returning single-row subquery returns more than one row 【发布时间】:2014-03-24 06:53:27 【问题描述】:我是 SQL 新手,遇到了一个查询问题。
我有 3 个表employees、departments 和salary_paid。 我正在尝试通过给出这个条件来更新salary_paid 表中的奖金列
give 10% bonus on total salary to the employees who are not in IT departments.
我想出了这个查询
update salary_paid
set bonus=(select (0.1*total_salary) "Bonus"
from salary_paid, departments, employees
where
employees.department_id=departments.department_id and
employees.employee_id=salary_paid.employee_id and
departments.department_name!='IT')
;
但是它返回这个错误
ORA-01427: 单行子查询返回多于一行
我对此一无所知,请帮忙。 在此先感谢
【问题讨论】:
【参考方案1】:您的内部查询 (select (0.1*total_salary) "Bonus" from salary_paid
返回多个值,因此无法分配给 bounus 列。
尝试使用这样的连接进行更新
UPDATE
(SELECT salary_paid.bonus as oldBonus, 0.1*salary_paid.total_salary as newBounus
FROM salary_paid
INNER JOIN employees
ON salary_paid.employee_id = employees.employee_id
INNER JOIN departments
ON departments.department_id = employees.department_id
WHERE departments.department_name != 'IT'
) t
SET t.oldBonus= t.newBounus
【讨论】:
这个查询效果很好。谢谢芽。但是出于好奇,我试图通过使用 where 子句的正常连接来执行相同的查询,但它似乎不起作用。【参考方案2】:试试这个:
UPDATE
(
SELECT *
FROM employees e LEFT JOIN salary_paid sp ON e.employee_id = sp.employee_id
LEFT JOIN departments d ON d.department_id = e.department_id
) t
SET t.bonus = 0.1 * t.total_salary
WHERE t.department_name != 'IT';
您的查询正在使用子查询的结果更新表中的所有行。此外,子查询返回不止一行。设置值时,子查询应始终返回单行单列。
在Oracle中,这些问题都是通过使用join来解决的,如上图所示。这将使用来自各个 total_salary
列的值更新 bonus
列。无需使用子查询。
【讨论】:
【参考方案3】:子查询应该总是返回单行作为回报。但是您使用选择查询到达这里多行。所以首先检查您的选择查询。
select (0.1*total_salary) "Bonus" from salary_paid, departments, employees
where employees.department_id=departments.department_id and employees.employee_id=salary_paid.employee_id and departments.department_name!='IT'
这个查询应该只有一个结果,但你正在尝试获取多行。
让我们尝试将 LIMIT 放入您的选择查询中
select (0.1*total_salary) "Bonus" from salary_paid, departments, employees
where employees.department_id=departments.department_id and employees.employee_id=salary_paid.employee_id and departments.department_name!='IT' limit 0,1
您需要更改您的选择查询以获取单行。
【讨论】:
你好,我还没有实际实现过limit功能,是不是类似于rownum的限制?此外,查询似乎没有执行。【参考方案4】:试试这个
update salary_paid a,departments b, employees c set a.bonus=(0.1*a.total_salary) "Bonus"
where c.department_id=b.department_id and c.employee_id=a.employee_id and b.department_name!='IT';
CMIIW
【讨论】:
AFAIK 多个表不能在更新语句中使用?无论哪种方式,这个查询显然都会返回缺少 SET 关键字错误【参考方案5】:我想更新 hr 用户的电子邮件,但遇到了同样的问题,然后我来了,这对我有用
update (select email as oldemail, substr(first_name,1,1)||''||last_name||''||'@gmail.com' as email from employees
inner join departments
on
employees.department_id= departments.department_id
)t
set t.oldemail=t.email
【讨论】:
以上是关于返回单行子查询的更新语句返回多于一行的主要内容,如果未能解决你的问题,请参考以下文章
ORA-01427: 单行子查询返回多于一行 ,,WHEN USING SELECT COUNT