返回单行子查询的更新语句返回多于一行

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

单行子查询在 Oracle 中返回多于一行

查询返回:ORA-01427 单行子查询返回多于一行

单行子查询返回多于一行

Oracle SQL:ORA-01427:单行子查询返回多于一行

ORA-01427 单行子查询返回多于一行