【问题标题】: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: 单行子查询返回多于一行

我对此一无所知,请帮忙。 在此先感谢

【问题讨论】:

    标签: mysql sql oracle


    【解决方案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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-30
        • 1970-01-01
        • 1970-01-01
        • 2017-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多