Insert and Update in Single Table using Merge? - oracle

I want to Update or insert Oracle Table based on condition.
Consider that in the table have 2 columns (like id and name), one or more name having the same id. In this situation i want to check the id and name (like 1,'Buyer'), if its exist then i want to update name 'Buyer' to 'Service Provider'. otherwise i want to just insert the values (1,'Service Provider').
I tried this through Merge, but it's update all the name column of id 1 to 'Service Provider'.
merge into party_type p
using (select 1 party_id, 'Buyer' party_type from dual) t
on (t.party_id = p.party_id)
when matched then
update set party_type = 'Service Provider'
when not matched then
insert (party_id,party_type) values(1,'Service Provider');
Available data in the table:
1 Buyer
1 Buyer Agent
1 Vendor
Thanks in advance.

you need to join on both columns
merge into party_type p
using (select 1 party_id, 'Buyer' party_type from dual) t
on (t.party_id = p.party_id and t.party_type = p.party_type)
when matched then
update set party_type = 'Service Provider'
when not matched then
insert (party_id,party_type) values(1,'Service Provider');

Related

I have a SQL table which consists of employee details and I have 3 update statements that works separately and want to merge it to 1 single starment

I have a SQL table which consists of employee details and my problem is I have three separate updates statements and want to club it together so that I can create a procedure which updates the table in such a way that it shows the salary including the bonus and the latest salary date which makes use of another bonus table
1]update employee_1 set employee_1.salary=(select sum(bonus_1.bonus_amount)from bonus_1 where employee_1.employee_id=bonus_1.employee_id GROUP by bonus_1.employee_id);
2]update employee_1 set employee_1.last_bonus_date=(select max(bonus_1.bonus_date)from bonus_1 where employee_1.employee_id=bonus_1.employee_id GROUP by bonus_1.employee_id);
3]update employee_1 set salary=salary+old_salary;
Basically need to combine these update statements so that I can use it in a procedure
You should've posted tables' description and sample data that illustrate the problem.
To me, it looks as if a single MERGE statement does the whole job (i.e. combines your 3 queries into 1):
merge into employee_1 a
using bonus_1 b
on (a.employee_id = b.employee_id)
when matched then update set
a.salary = a.salary + b.bonus_amount,
a.last_bonus_date = b.bonus_date;
You can use a MERGE statement and perform the aggregation in the USING clause:
MERGE INTO employee_1 e
USING (
SELECT employee_id,
SUM(bonus_amount) AS total_bonus,
MAX(bonus_date) AS last_date
FROM bonus_1
GROUP BY employee_id
) b
ON (e.employee_id = b.employee_id)
WHEN MATCHED THEN
UPDATE
SET salary = e.salary + b.total_bonus,
last_bonus_date = b.last_date;

SELECT within UPDATE gives an error

I am getting SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table error on this statement:
UPDATE
(
SELECT CELLS.NUM, UND.CLIENT_PARAMS
FROM CELLS
LEFT OUTER JOIN UND
ON CELLS.UND_ID = UND.ID
WHERE CELLS.SASE = 1
) t
SET t.CLIENT_PARAMS = 'test';
I would like to update CLIENT_PARAMS field for all rows, which select returns.
The most straightforward (though possibly not the most efficient) way to update rows in one table which correspond directly to rows in another table via an identity column would be to use WHERE table1.column IN (SELECT id FROM table2 WHERE ...).
In this case:
UPDATE UND
SET client_params = 'test'
WHERE id IN
(SELECT und_id
FROM CELLS
WHERE SASE=1)
Try this
UPDATE und u
SET client_params = 'test'
WHERE EXISTS
(SELECT 1
FROM cells c
WHERE C.SASE = 1
AND c.und_id = u.id)

Copy records from one table to another with pl-sql

I want to copy records from one table to another.
The only records from table 1 that will be copied to table 2 are the ones that still dont exist in table 2.
If duplicate records exists in Table 1 then only be copied to table 2 the record with the larger size name.
I could already implement a query that almost does what I want.
The problem I have is when there are names with the same maximum size of characters.
In these cases, my query returns more than one record and I just want to insert one new record in table 2.
Does anyone know how I can fix this?
Here is my code:
For x in (Select distinct xdd.id_t, xdd.name_t
From table1 xdd
Where xdd.id_t not in (Select distinct det.id_t2
From table2 det)
And LENGTH(xdd.name_t) in (Select Max(LENGTH(xdd2.name_t))
From table1 xdd2
Where xdd2.id_t = xdd.id_t)
) Loop
Insert into id_t2 (id_t2, name_t2)
Values (x.id_t, x.name_t);
End loop;
Can you give me an example to solve this?
Sure. If I understood requirements correctly, then the merge statement will look similar to this one:
We use row_number() analytic function to choose a duplicate record with longer name_t
merge into table_two t2
using(
select id_t
, name_t
from (select id_t
, name_t
, row_number() over(partition by id_t
order by length(name_t) desc) as rn
from table_one) q
where q.rn = 1
) t1
on (t2.id_t = t1.id_t)
when not matched then
insert(id_t, name_t)
values(t1.id_t, t1.name_t)
SQLFiddle demo
This is a merge statement that should "upsert" data from table 1 into table 2. Matching keys should update only when the name field in table1 is greater than that of table 2. And inserts should occur when keys from table one are not matched to table 2.
MERGE INTO table2 D
USING (SELECT table1.id_t, table1.name_t FROM table1) S
ON (D.id_t2 = S.id_t)
WHEN MATCHED THEN UPDATE SET D.name_t2 = S.name_t
WHERE (LENGTH(S.name_t) > LENGTH(D.name_t2))
WHEN NOT MATCHED THEN INSERT (D.id_t, D.name_t)
VALUES (S.id_t2, S.name_t2);

Oracle-update multiple row value where the the id column equals specific values

I am new in oracle and I want to update multiple row value where the column id = 1 , 2.
I tried this :
update Tester
set employee_phone_number = ( 0789456123,0789456321)
where employee_id in (1,2);
but it gives me "missing right parenthesis"
any help please and thanks in advance.
Another approach:
merge into
tester
using (
select 1 id,'0123456785' employee_phone_number from dual union all
select 2 id,'0123456786' employee_phone_number from dual) new_values
on (
tester.id = new_values.id)
when matched then update
set employee_phone_number = new_values.employee_phone_number;
More words, but allows the values to be specified in only one place and extends to allow inserts where the id does not already exist.
http://sqlfiddle.com/#!4/8fc86/3
Try this instead:
update Tester
set employee_phone_number = CASE WHEN employee_id = 1 THEN 0789456123
WHEN employee_id = 2 THEN 0789456321
END
where employee_id in (1,2);

query to create same group id for all duplicate record

I have oracle table contain field like
rowindx,mdnnumber,poivalue,groupid
I want to assign same groupid to all record that are duplicate via poivalue.
I create function for that but i want to know is it possible with sql query ? how ?
Assuming I can use the poivalue as the group ID sure.
Update table set GROUPID=PoiValue
where POIValue in (
Select POIValue
from table
group by poivalue
having count(poivalue) > 1)
that should generate the groupid as 1,2,3...
update t
set groupid =
(select groupid
from (select poivalue, ROWNUM groupid
from (select distinct poivalue from t order by poivalue) t2) t2
where t2.poivalue = t.poivalue)

Resources