如何在单个语句中更新整个列
Posted
技术标签:
【中文标题】如何在单个语句中更新整个列【英文标题】:How to update entire column in a single statement 【发布时间】:2020-04-08 19:18:18 【问题描述】:普通的HR方案,如何一次请求更新一整列?
我收到此错误:
ORA-01427: 单行子查询返回多于一行
update depts
set tot_dept_sal =
( select sum(e.salary)
from depts d, employees e
where e.department_id = d.department_id
group by d.department_name );
有一个表DEPTS:
department_id department_name Tot_dept_sal
------------- ---------------- ------------
10 Administration null
20 Marketing null
30 Purchasing null
40 Human Resources null
...
270 Payroll null
和员工:
employee_id last_name salary departments_id
------------- ---------- ------ --------------
100 King 24000 90
101 Kochhar 17000 90
102 De Haan 17000 90
103 Hunold 9000 60
104 Ernst 6000 60
【问题讨论】:
您需要共享这些表中的一些示例数据以及您尝试更新的内容。您的查询按原样没有多大意义。 欢迎来到 Stack Overflow。为了帮助我们帮助您,请使用Tour 并通读How To Ask,然后edit() 您的问题以及创建a Minimal, Complete, and Verifiable Example for database-related questions 所需的详细信息。 今日提示:切换到现代、明确的JOIN
语法。更容易编写(没有错误),更容易阅读(和维护),并且如果需要更容易转换为外连接! (他们真的在 2020 年教过古老的逗号分隔的隐式连接?!?可怕......)
depts
和 departments
应该是同一张桌子吗?如果是这样,为什么要在子查询中第二次引用更新的表?无论哪种方式,您希望目标表和子查询如何关联?说明您的代码发生了什么通常也很有用 - 大概您收到 ORA-01427 错误?
【参考方案1】:
您已经在外部UPDATE
中获得了departments
表,您可以将子查询与外部查询相关联,而不是在子查询中再次加入它:
update departments d
set tot_dept_sal = (
select sum(e.salary)
from employees e
where d.DEPARTMENT_ID=e.DEPARTMENT_ID
group by d.department_id
);
因此,对于您的示例数据(更新为具有与 departments
表匹配的 employees
的 depatment_id
值):
CREATE TABLE departments ( department_id, department_name, Tot_dept_sal ) AS
SELECT 10, 'Administration', CAST( null AS NUMBER(8,0) ) FROM DUAL UNION ALL
SELECT 20, 'Marketing', CAST( null AS NUMBER(8,0) ) FROM DUAL UNION ALL
SELECT 30, 'Purchasing', CAST( null AS NUMBER(8,0) ) FROM DUAL UNION ALL
SELECT 40, 'Human Resources', CAST( null AS NUMBER(8,0) ) FROM DUAL UNION ALL
SELECT 270, 'Payroll', CAST( null AS NUMBER(8,0) ) FROM DUAL;
CREATE TABLE employees ( employee_id, last_name, salary, department_id ) AS
SELECT 100, 'King', 24000, 10 FROM DUAL UNION ALL
SELECT 101, 'Kochhar', 17000, 10 FROM DUAL UNION ALL
SELECT 102, 'De Haan', 17000, 20 FROM DUAL UNION ALL
SELECT 103, 'Hunold', 9000, 20 FROM DUAL UNION ALL
SELECT 104, 'Ernst', 6000, 270 FROM DUAL;
然后在运行UPDATE
语句后:
SELECT * FROM DEPARTMENTS;
输出:
DEPARTMENT_ID |部门名称 | TOT_DEPT_SAL ------------: | :---------------- | ------------: 10 |管理 | 41000 20 |营销 | 26000 30 |采购 | 空 40 |人力资源 | 空 270 |工资单| 6000
db小提琴here
【讨论】:
您甚至不需要这里的group by
子句 - 虽然*8-) 无法确定它是否增加了清晰度【参考方案2】:
您可以按如下方式使用 MERGE 语句:
MERGE INTO departments TRG
USING (SELECT department_id, SUM(salary) AS SALARY
FROM employees
GROUP BY department_id) SRC
ON (TRG.department_id = SRC.department_id)
WHEN MATCHED THEN UPDATE SET TRG.Tot_dept_sal = SRC.SALARY;
【讨论】:
以上是关于如何在单个语句中更新整个列的主要内容,如果未能解决你的问题,请参考以下文章