I have an ORACLE query which does not work for this query.
UPDATE emp a set a.Enq_Status = 'PROGRESS'
where exists (select * from emp a, Data b
WHERE a.SA_Enq_Status is NULL
and a.EQ_Status = 'ACTIVATED'
and a.Activation_Return_Code = 0
and a.Alert_Code > 0
and a.User_Id = b.User_Id
and (b.Is_Associate is NULL or b.Is_Associate = 0)
and (b.Stk_Schd is NULL)
and (b.Stk_Dis_Amt is NULL)
);
My Problem is I want to update mutiple records in the table emp (A) to status to 'PROGRESS'.But when executing this query all records in a.Enq_status is changes.Please help me in this.Updation is not correct.Please help me in this
You have specified table emp both in the update query and the subquery too, Oracle will treat these as seperate tables.
You need a correlated subquery:
UPDATE emp a
set a.Enq_Status = 'PROGRESS'
where exists (select 'X'
from Data b
WHERE a.SA_Enq_Status is NULL
and a.EQ_Status = 'ACTIVATED'
and a.Activation_Return_Code = 0
and a.Alert_Code > 0
and a.User_Id = b.User_Id
and (b.Is_Associate is NULL or b.Is_Associate = 0)
and (b.Stk_Schd is NULL)
and (b.Stk_Dis_Amt is NULL));
You could probably just update the emp table without the need for the subquery though if you link to the Data table in the where clause...
Your update statement will update all the records in emp table because you don't specify the records to update. If your sub-query returns at least one row, the all the emp records will be updated. If it returns no rows, then none of the records will be updated.
Change your update like this:
UPDATE emp SET Enq_Status = 'PROGRESS'
WHERE id in
(SELECT a.id
FROM emp a, Data b
WHERE a.SA_Enq_Status is NULL and a.EQ_Status = 'ACTIVATED'
and a.Activation_Return_Code = 0 and a.Alert_Code > 0
and a.User_Id = b.User_Id and (b.Is_Associate is NULL or b.Is_Associate = 0)
and (b.Stk_Schd is NULL)and (b.Stk_Dis_Amt is NULL)
);
Try:
UPDATE emp a
SET a.enq_status = 'PROGRESS'
WHERE a.sa_enq_status IS NULL
AND a.eq_status = 'ACTIVATED'
AND a.activation_return_code = 0
AND a.alert_code > 0
AND EXISTS
(SELECT 'X'
FROM data b
WHERE a.user_id = b.user_id
AND ( b.is_associate IS NULL OR b.is_associate = 0 )
AND b.stk_schd IS NULL
AND b.stk_dis_amt IS NULL);
Related
I have a table with the following fields:
ID, VALUES, VARIAB
Im trying to SUM the field VALUES, but it needs to be grouped by ID.
And the Subselect doesnt accept multiple lines. (When i use it with just 1 ID, works fine).
BEGIN
UPDATE TBL2
SET SOMA =
(SELECT SUM(x.VALUES)
FROM TBL3 x INNER JOIN TBL2 y
ON y.ID = x.ID
WHERE y.ID = x.ID AND X.VARIAB = 1
GROUP BY x.ID
);
END;
Im using ORACLE DB, if anyone comment this ill be very gratefull.
Sorry for my english flaws.
To update multiple records at once and/or do an upsert, use MERGE statement like this :
MERGE INTO TBL2 T2 USING (
SELECT x.id,SUM(x.VALUES) total
FROM TBL3 x
WHERE x.VARIAB = 1
GROUP BY x.ID
) T3 ON (T2.ID = T3.ID)
WHEN MATCHED THEN UPDATE
SET T2.SOMA = T3.TOTAL
The issue is that your update statement isn't correlated - ie. your subquery has no reference to the table being updated.
You could change it to:
update tbl2 t2
set soma = (select sum(t3.values)
from tbl3 t3
where t2.id = t3.id
and t3.variab = 1);
I need to update a list of record given by a subquery, sniffing around on the web I tried this structure:
UPDATE
(
SELECT
a.COL1
FROM
TABLE1 a,
TABLE2 b
WHERE
a.field1 = b.field1
) update_tbl
SET
update_tbl.COL1 = 'VALUE'
But it returns to me this Oracle error:
-> ORA-01779: Cannot modify a column which maps to a non key-preserved table
My query is the following one:
UPDATE
(
SELECT
imp.*
FROM table1 imp
JOIN table2 sp ON imp.id_p = sp.id_p
JOIN table3 cs ON sp.id_s = cs.id_s
JOIN table4 cb ON cb.id_c = cs.id_c
WHERE
imp.id_b = cb.id_b
AND (
(to_char(imp.p,'yyyymm') < to_char(cb.data_in,'yyyymm')) OR
(cb.data_fi IS NOT NULL AND to_char(imp.p,'yyyymm') > to_char(cb.data_fi,'yyyymm'))
)
and (
(imp.v is not null) or
(imp.v_s is not null and imp.v_s <> 0) or
(imp.imp_co is not null and imp.imp_co <> 0) or
(imp.imp_acc is not null and imp.imp_acc <> 0)
)
) i
SET
i.v = null,
i.v_s = 0,
i.imp_co = 0,
i.imp_acc = 0,
i.ID_S_CONT = 'N',
i.ID_T_COMP = 'P',
i.date_upd = SYSDATE,
i.user_upd = 'SeR'
The subquery return 82 rows (tested now), and I do want to modify only that rows, What am I doing wrong?
I think you are updating to imp table. so you can try MERGE like below
MERGE INTO
IMP A
USING
( SELECT
imp.*
FROM table1 imp
JOIN table2 sp ON imp.id_p = sp.id_p
JOIN table3 cs ON sp.id_s = cs.id_s
JOIN table4 cb ON cb.id_c = cs.id_c
WHERE
imp.id_b = cb.id_b
AND (
(to_char(imp.p,'yyyymm') < to_char(cb.data_in,'yyyymm')) OR
(cb.data_fi IS NOT NULL AND to_char(imp.p,'yyyymm') >
to_char(cb.data_fi,'yyyymm'))
)
and (
(imp.v is not null) or
(imp.v_s is not null and imp.v_s <> 0) or
(imp.imp_co is not null and imp.imp_co <> 0) or
(imp.imp_acc is not null and imp.imp_acc <> 0)
)) B
ON (A.ID =B.ID)
WHEN MATCHED THEN
UPDATE SET
A.v = null,
A.v_s = 0,
A.imp_co = 0,
A.imp_acc = 0,
A.ID_S_CONT = 'N',
A.ID_T_COMP = 'P',
A.date_upd = SYSDATE,
A.user_upd = 'SeR'
Will update the table given by subquery. here A.ID =B.ID use the primary key.
Hi I have the following update query:
UPDATE buchung b
SET kst_id = (SELECT kst_id
FROM kostenstelle
WHERE b.Kostenstelle = kostenstelle)
I get the Error in the Topic and I know why.
My Question: Is it possible to update just the rows which are unique?
There are various ways to do this.
Add a WHERE clause that checks that for the specific b.kostenstelle value there is exactly one row in table kostenstelle:
update buchung b
set kst_id = (select kst_id
from kostenstelle
where b.Kostenstelle = kostenstelle)
where 1 = (select count(*)
from kostenstelle
where b.Kostenstelle = kostenstelle) ;
exactly as before, only using a different way to check for only one. It may be more efficient, with an index on kostenstelle (kostenstelle, kst_id):
update buchung b
set kst_id = (select kst_id
from kostenstelle
where b.Kostenstelle = kostenstelle)
where not exists
( select 0
from kostenstelle
where b.Kostenstelle = kostenstelle
having min(kst_id) < max(kst_id) -- the PK of kostenstelle
) ;
use the COUNT() window function to determine the count:
with upd as
( select b.kst_id,
k.kst_id as k_kst_id
count(distinct k.kst_id) over (partition by k.kostenstelle) as cnt
from buchung b
join kostenstelle
on b.Kostenstelle = k.kostenstelle
)
update upd
set kst_id = k_kst_id
where cnt = 1 ;
and a variation on the last one, where it may be more obvious what the code is doing:
with unq as
( select kostenstelle,
min(kst_id) as kst_id
from kostenstelle
group by kostenstelle
having min(kst_id) = max(kst_id)
) ,
upd as
( select b.kst_id,
k.kst_id as k_kst_id
from buchung b
join unq k
on b.Kostenstelle = k.kostenstelle
)
update upd
set kst_id = k_kst_id ;
I have a table called ‘MainTable’ with following data
Another table called ‘ChildTable’ with following data (foreighn key Number)
Now I want to fetch those records from ‘ChildTable’ if there exists at least one ‘S’ status.
But if any other record for this number id ‘R’ then I don’t want to fetch it
Something like this-
I tried following
Select m.Number, c.Status from MainTable m, ChildTable c
where EXISTS (SELECT NULL
FROM ChildTable c2
WHERE c2.status =’S’ and c2.status <> ‘R’
AND c2.number = m.number)
But here I am getting record having ‘R’ status also, what I am doing wrong?
You can try something like this
select num, status
from
(select id, num, status,
sum(decode(status, 'R', 1, 0)) over (partition by num) Rs,
sum(decode(status, 'S', 1, 0)) over (partition by num) Ss
from child_table) t
where t.Rs = 0 and t.Ss >= 1
-- and status = 'S'
Here is a sqlfiddle demo
The child records with 'R' might be associated with a maintable record that also has another child record with status 'S' -- that is what your query is asking for.
Select
m.Number,
c.Status
from MainTable m
join ChildTable c on c.number = m.number
where EXISTS (
SELECT NULL
FROM ChildTable c2
WHERE c2.status =’S’
AND c2.number = m.number) and
NOT EXISTS (
SELECT NULL
FROM ChildTable c2
WHERE c2.status =’R’
AND c2.number = m.number)
WITH ChildrenWithS AS (
SELECT Number
FROM ChildTable
WHERE Status = 'S'
)
,ChildrenWithR AS (
SELECT Number
FROM ChildTable
WHERE Status = 'R'
)
SELECT MaintTable.Number
,ChildTable.Status
FROM MainTable
INNER JOIN ChildTable
ON MainTable.Number = ChildTable.Number
WHERE MainTable.Number IN (SELECT Number FROM ChildrenWithS)
AND MainTable.Number NOT IN (SELECT Number FROM ChildrenWithR)
I have two tables, one parent and one child table. Child will have many rows for parent_id. Both table has status column. Possible values are Active and Deleted.
I want to do this. If for a parent id all children have Deleted status, have to mark parent also as Deleted from Active status. Can it be done in single update query?
Thanks in advance.
How about something like this?
UPDATE parent_table pt SET deleted = 'Y' WHERE deleted = 'N' AND id NOT IN
(SELECT parent_id FROM child_table ct WHERE deleted = 'N' AND ct.parent_id = pt.id)
Yes:
update parent
set status = 'Deleted'
where status = 'Active'
and not exists ( select null from child
where child.id = parent.id
and child.status <> 'Deleted')
UPDATE parent_table
set status = 'deleted'
WHERE status = 'active'
AND id in (
SELECT parent_id
FROM (
SELECT
parent_id
, count(*) total
, sum (CASE staus WHEN 'deleted' THEN 1 ELSE 0 END) deleted
FROM child_table
group by parent_id
)
WHERE total = deleted
)