Как обновить весь столбец в одном выражении - PullRequest
0 голосов
/ 08 апреля 2020

Обычная схема управления персоналом, как обновить весь столбец одним запросом?

Я получаю эту ошибку:

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  

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Вы уже получили таблицу departments во внешнем UPDATE, и вы можете просто сопоставить подзапрос с внешним запросом, а не присоединяться к нему во второй раз в подзапросе:

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
);

Итак, для ваших примеров данных (обновлено, чтобы иметь значения depatment_id для employees, которые соответствуют таблице departments):

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 | DEPARTMENT_NAME | TOT_DEPT_SAL
------------: | :-------------- | -----------:
           10 | Administration  |        41000
           20 | Marketing       |        26000
           30 | Purchasing      |         <em>null</em>
           40 | Human Resources |         <em>null</em>
          270 | Payroll         |         6000

дБ <> скрипка здесь

0 голосов
/ 09 апреля 2020

Вы можете использовать инструкцию 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;
...