How to use UPDATE JOIN correctly? - sql

I tried to update a table row as below:
update EMPLOYEE set Salary=Salary * 1.15 where Dno=1;
which works fine, but I wanted to learn how to use UPDATE JOIN. so I use the Department Name instead of DNo.
I wrote below code:
update EMPLOYEE set Salary=e.Salary * 1.15 from EMPLOYEE e join DEPARTMENT d on e.DNo=d.DNumber where d.DName='Headquarters';
But the result for above code is that the SQL Command updates all the rows in EMPLOYEE table.
Where did I do wrong?

In BigQuery, change this to a filter in the where clause:
update EMPLOYEE e
set Salary = Salary * 1.15
where exists (select 1
from DEPARTMENT d
where d.DNumber = e.DNo and
d.DName = 'Headquarters'
);
The above is standard SQL and should work in any database. If you want a FROM clause, then use:
update EMPLOYEE e
set Salary = e.Salary * 1.15
from DEPARTMENT d
where d.DNumber = e.DNo and
d.DName = 'Headquarters';
There are (at least) two different ways of implementing FROM in an update, the "SQL Server method" and the "Postgres" method. In the SQL Server method, the table being updated should be in the FROM clause. In the "Postgres method", the table cannot be in the FROM clause. BigQuery adheres to the "Postgres method".
The above actually works in both methods, though.

Try to use table alias name in update
update Emp
Set Salary = Emp.Salary * 1.15
From EMPLOYEE As Emp
join DEPARTMENT As dep On Emp.DNo = dep.DNumber
Where dep.DName = 'Headquarters';

Related

subquery and join not giving the same result

1
select *
from employees
where salary > (select max(salary) from employees where department_id=50)
2
select *
from employees e left join
employees d
on e.DEPARTMENT_ID =d.DEPARTMENT_ID
where d.salary > (select max(salary) from employees where department_id=50)
why the second query is giving multiple record
i want achieve the same result as of 1st query using join.....
Thanks in Advance......
Rocky, the first select is correct. Why do you want to do any join? Without further information the objective of the second select is not clear (nonsense).
I can't see the point about joining against the same table by DEPARTMENT_ID. Anyway, the problem about duplicates is because you are joining the same two tables by a key is not pk, basically you are multiplyng each employee for all the employees of the same department. This version eliminate duplicates but still has no improvement from the first one.
select *
from employees e left join
employees d
on e.employee_ID = d.employee_ID
where d.salary > (select max(salary) from employees where department_id=50)
You are probably looking for an anti join. This is a pattern mainly used in a young DBMS where IN and EXISTS clauses are slow compared to joins, because the developers focused on joins only.
You are looking for all employees whose salaries are greater than all salaries in department 50. With other words: WHERE NOT EXISTS a salary greater or equal in department 50.
Your query can hence be written as:
select *
from employees e
where not exists
(
select null
from employees e50
where e50.department_id = 50
and e50.salary >= e.salary
);
As an anti join (an outer join where you dismiss all matches):
select *
from employees e
left join employees e50 on e50.department_id = 50 and e50.salary >= e.salary
where e50.salary is null;

Create table as Select, then Update statement with JOIN in Oracle

I'm using Oracle HR database.
I was wondering why the following query isn't working:
create table ecopy
as select *
from employees;
create table dcopy
as select *
from departments;
UPDATE (select d.location_id, e.salary
from ecopy e inner join dcopy d
on e.department_id=d.department_id)
set salary = salary+1
where location_id = 1800
SQL Error: ORA-01779: cannot modify a column which maps to a non key->preserved table
While the this one, on the origin tables is doing it's job:
UPDATE (select d.location_id, e.salary
from employees e inner join departments d
on e.department_id=d.department_id)
set salary = salary+1
where location_id = 1800
Could anyone explain it to me?
Here is the explanation:
In your real life your relation supported by keys - reference constraint
employee.department_id(MANY) = departments.department_id(ONE)
In the case of UPDATE with JOIN, you can update only columns in your "MANY" table and only if they have real reference.
Your Create as select. . . tables definitely don't have these references, hence Oracle optimizer throws this error.
Here are some references
Reference 1
Reference 2

How to change this db2 merge query?

can someone help me? i am trying to convert the following merge into another query and i am allowed only to use insert and update once:
MERGE INTO MYEMPLOYEE ME USING EMPLOYEE E ON ME.EMPNO = E.EMPNO
WHEN MATCHED THEN
UPDATE SET ME.SALARY = CASE WHEN ME.SALARY > E.SALARY THEN ME.SALARY ELSE E.SALARY END
WHEN NOT MATCHED THEN
INSERT VALUES(E.EMPNO, E.FIRSTNME, E.MIDINIT, E.LASTNAME, E.WORKDEPT, E.PHONENO, E.HIREDATE, E.JOB, E.EDLEVEL, E.SEX, E.BIRTHDATE, E.SALARY, E.BONUS, E.COMM);
How can I achieve this? the above merge copies the data if not exists, and if it exists it checks for the salary and selects the higher one and copies that one.
how can I achieve the same thing by only using one insert and one update? Can someone give me hints, please?
Thanks in advance :)
The purpose of the MERGE command is suppose to take into account multiple actions of UPDATE, INSERT, DELETE. MERGE statement explained
If you cannot/unable to use MERGE, then you have to resort to doing each request individually.
UPDATE MYEMPLOYEE ME
SET ME.SALARY = (
SELECT CASE WHEN ME.SALARY > E.SALARY THEN ME.SALARY ELSE E.SALARY END
FROM EMPLOYEE E
WHERE ME.EMPNO = E.EMPNO
)
WHERE EXISTS(
SELECT 1
FROM EMPLOYEE E
WHERE ME.EMPNO = E.EMPNO
);
Then do an insert where the employee don't exist in the master table.
INSERT INTO MYEMPLOYEE ME
SELECT *
FROM EMPLOYEE E
LEFT OUTER JOIN MYEMPLOEE ME ON E.EMPNO=ME.EMPNO
WHERE ME.EMPNO IS NULL;
If you need to do in one full sweep you can use the IMPORT command. But then you are dealing with files. You would need to export the EMPLOYEE table (probably with salary already formatted) and then import using the INSERT_REPLACE ability.
After trying I noticed that the INSERT code should actually be like this:
1) Don't use the Name ME twice
2) Select the necessary columns because after the join there are twice the column count
INSERT INTO MYEMPLOYEE (
SELECT E.EMPNO, E.FIRSTNME, E.MIDINIT, E.LASTNAME, E.WORKDEPT, E.PHONENO, E.HIREDATE, E.JOB, E.EDLEVEL, E.SEX, E.BIRTHDATE, E.SALARY, E.BONUS, E.COMM
FROM EMPLOYEE E LEFT OUTER JOIN MYEMPLOYEE ME ON E.EMPNO = ME.EMPNO WHERE ME.EMPNO IS NULL
);

Update values using joins and where

I've tried the following commands:
UPDATE staff SET salary = (salary * 1.1)
where branchno = (select branchno from branch where city = 'London');
update salary from staff s join branch b on s.branchno = b.branchno
where b.city = 'London' set salary = salary * 1.1;
However, I get this back as an error:
> ERROR: more than one row returned by a subquery used as an expression
Any ideas? essentially I want to update all members of staff's salaries by 10% that live in London, but I must join the Staff and Branch table to get the branches location.
Your query transformed to proper join syntax:
UPDATE staff s
SET salary = (salary * 1.1)
FROM branch b
WHERE b.city = 'London'
AND s.branchno = b.branchno;
This avoids the reported error. The manual has more on UPDATE.

Why the query is not working?

I have made the schema on the sqlfiddle.
I am beginner to database.
http://sqlfiddle.com/#!4/21535
I want to get all employees in the cleaning department
select * from emp,department
where dname = 'cleaning'
and dno = dnum;
select * from emp e,department d
where d.dname = 'cleaning'
and e.dno = d.dnum;
select * from emp as e,department as d
where d.dname = 'cleaning'
and e.dno = d.dnum;
But the third query is not working . why?
I am reading from the book Fundamentals_of_Database_Systems.(Elmasri)
There are many queries which has used as.
Am I wrong?
select * from emp e,department d
where d.dname = 'cleaning'
and e.dno = d.dnum;
works fine
Just get rif of as. It is used with columns
UPDATE with join
select * from emp e JOIN department d ON e.dno = d.dnum
where d.dname = 'cleaning';
Oracle doesn't support using statement AS to determine alias for tables. In SQL standart it can be used only for change name of columns in query result. However, most of DB systems support as also like creating aliase for table in query.