I have written a query where I want to just update some of the LINK_ID. But it is updating all the rows in that table.
Here is my query
UPDATE APP_FIBERINV.TBL_FIBER_INV_CMPAPPROVED_INFO
SET NE_LENGTH =
(select MAINT_ZONE_NE_SPAN_LENGTH from APP_FIBERINV.TBL_FIBER_INV_JOBS WHERE LINK_ID IN ('MORV_1020','ANND_1017','BBSR_1047','DLHI_5417','MYSR_0104'));
I still doubt that the update statement you have posted updates all rows in the table. It must throw an error
ORA-01427: single-row subquery returns more than one row
instead, because your subquery returns five rows where it must be one, as you must find one value for each row you want to update.
This means your subquery is wrong. It selects five rows, where it must select one. You don't want to find the five values for 'MORV_1020', 'ANND_1017', but the one value for the link ID of the row you are updating.
You also want to update certain rows (those with the five link IDs), so you must add a WHERE clause at the end of your update statement.
UPDATE app_fiberinv.tbl_fiber_inv_cmpapproved_info i
SET ne_length =
(
SELECT j.maint_zone_ne_span_length
FROM app_fiberinv.tbl_fiber_inv_jobs j
WHERE j.link_id = i.span_link_id
)
WHERE span_link_id IN ('MORV_1020', 'ANND_1017', 'BBSR_1047', 'DLHI_5417', 'MYSR_0104');
Assuming both tables share the LINK_ID as primary and foreign key, you could just use a MERGE:
MERGE INTO APP_FIBERINV.TBL_FIBER_INV_CMPAPPROVED_INFO APPR_NFO
USING (
SELECT LINK_ID, MAINT_ZONE_NE_SPAN_LENGTH
FROM APP_FIBERINV.TBL_FIBER_INV_JOBS
WHERE LINK_ID IN ('MORV_1020','ANND_1017','BBSR_1047','DLHI_5417','MYSR_0104')
) INV_JOBS
ON ( APPR_NFO.SPAN_LINK_ID = INV_JOBS.LINK_ID)
WHEN MATCHED THEN UPDATE SET APPR_NFO.NE_LENGTH = INV_JOBS.MAINT_ZONE_NE_SPAN_LENGTH;
let's assume I have a table tab1 in my Oracle DB 12.1, which has a column record_id (type NUMBER) and many other columns, among them a column named exchg_id.
This record_id is always empty when a batch of new rows gets inserted into the table. What I need to do is to populate the record_id with values 1..N for all rows that satisfy a condition ...WHERE EXCHG_ID = 'something' and number of such rows is N. Of course I know how to do this procedurally (in a for-loop), but I'd like to know if there's an faster way using a single UPDATE statement. I imagine something like this:
UPDATE tab1 SET record_id = {1..N} WHERE exchg_id = 'something';
Many thanks for your help!
UPDATE: the order of the rows is not important, I need no specific ordering. I just need unique record_id's 1..N for any given exchg_id.
You could use rownum to set record_id to 1 to N :
UPDATE tab1 SET record_id = rownum WHERE exchg_id = 'something';
If you have some offset, say 10, then use rownum + 10
I need to update value in table with (own value) - (value in other table Like) for an id
I have tried this
UPDATE FULLTABLE
SET FULLTABLE.Balance = FULLTABLE.Balance - AdvBalance.balance
WHERE FULLTABLE.id= AdvBalance.advid;
and this
update fulltable f set f.balance = ( f.balance -
select a.balance from advbalance a where a.advid=f.advertiserID)
first one is throwing error that invalid identifier. second one some other error.
I am using oracle db.
Please suggest a way to do this.
Thanks
You need a subselect to get the value from another table:
UPDATE FULLTABLE ft
SET ft.Balance = ft.Balance - (SELECT ab.balance
FROM AdvBalance ab
WHERE ft.id = ab.advid);
This will fail if it is possible that the subquery will return more than one row, but if this is the case, then you must decide how to find the right value to be subtracted.
Hi Guys I have Two tables (MIGADM.CORPMISCELLANEOUSINFO and CRMUSER.PREFERENCES) and Each Has a field called PREFERENCE_ID and ORGKEY. I want to Update the Preference ID for MIGADM.CORPMISCELLANEOUSINFO with Preference_ID from CRMUSER.PREFERENCES for Each Corresponding ORGKEY. SO I wrote this Query;
update migadm.CORPMISCELLANEOUSINFO s set s.PREFERENCE_ID = (
select e.PREFERENCE_ID from crmuser.preferences e where s.ORGKEY = e.ORGKEY)
But I get:
ORA-01427: single-row subquery returns more than one row
What Should I do?
It means the columns you have selected are not unique enough to identify one row in your source table. Your first step would be to identify those columns.
To see the set of rows that have this problem, run this query.
select e.origkey,
count(*)
from crmuser.preferences e
group by e.origkey
having count(*) > 1
eg : for origkey of 2, let's say there are two rows in the preferences table.
orig_key PREFERENCE_ID
2 202
2 201
Oracle is not sure which of these should be used to update the preference_id column in CORPMISCELLANEOUSINFO
identify the row where the subquery returns more than one row (You could use REJECT ERROR clause to do it for instance) or use the condition 'where rownum = 1'.
Here's my original question:
merging two data sets
Unfortunately I omitted some intircacies, that I'd like to elaborate here.
So I have two tables events_source_1 and events_source_2 tables. I have to produce the data set from those tables into resultant dataset (that I'd be able to insert into third table, but that's irrelevant).
events_source_1 contain historic event data and I have to do get the most recent event (for such I'm doing the following:
select event_type,b,c,max(event_date),null next_event_date
from events_source_1
group by event_type,b,c,event_date,null
events_source_2 contain the future event data and I have to do the following:
select event_type,b,c,null event_date, next_event_date
from events_source_2
where b>sysdate;
How to put outer join statement to fill the void (i.e. when same event_type,b,c found from event_source_2 then next_event_date will be filled with the first date found
GREATLY APPRECIATE FOR YOUR HELP IN ADVANCE.
Hope I got your question right. This should return the latest event_date of events_source_1 per event_type, b, c and add the lowest event_date of event_source_2.
Select es1.event_type, es1.b, es1.c,
Max(es1.event_date),
Min(es2.event_date) As next_event_date
From events_source_1 es1
Left Join events_source_2 es2 On ( es2.event_type = es1.event_type
And es2.b = es1.b
And es2.c = es1.c
)
Group By c1.event_type, c1.b, c1.c
You could just make the table where you need to select a max using a group by into a virtual table, and then do the full outer join as I provided in the answer to the prior question.
Add something like this to the top of the query:
with past_source as (
select event_type, b, c, max(event_date)
from event_source_1
group by event_type, b, c, event_date
)
Then you can use past_source as if it were an actual table, and continue your select right after the closing parens on the with clause shown.
I end up doing two step process: 1st step populates the data from event table 1, 2nd step MERGES the data between target (the dataset from 1st step) and another source. Please forgive me, but I had to obfuscate table name and omit some columns in the code below for legal reasons. Here's the SQL:
INSERT INTO EVENTS_TARGET (VEHICLE_ID,EVENT_TYPE_ID,CLIENT_ID,EVENT_DATE,CREATED_DATE)
select VEHICLE_ID, EVENT_TYPE_ID, DEALER_ID,
max(EVENT_INITIATED_DATE) EVENT_DATE, sysdate CREATED_DATE
FROM events_source_1
GROUP BY VEHICLE_ID, EVENT_TYPE_ID, DEALER_ID, sysdate;
Here's the second step:
MERGE INTO EVENTS_TARGET tgt
USING (
SELECT ee.VEHICLE_ID VEHICLE_ID, ee.POTENTIAL_EVENT_TYPE_ID POTENTIAL_EVENT_TYPE_ID, ee.CLIENT_ID CLIENT_ID,ee.POTENTIAL_EVENT_DATE POTENTIAL_EVENT_DATE FROM EVENTS_SOURCE_2 ee WHERE ee.POTENTIAL_EVENT_DATE>SYSDATE) src
ON (tgt.vehicle_id = src.VEHICLE_ID AND tgt.client_id=src.client_id AND tgt.EVENT_TYPE_ID=src.POTENTIAL_EVENT_TYPE_ID)
WHEN MATCHED THEN
UPDATE SET tgt.NEXT_EVENT_DATE=src.POTENTIAL_EVENT_DATE
WHEN NOT MATCHED THEN
insert (tgt.VEHICLE_ID,tgt.EVENT_TYPE_ID,tgt.CLIENT_ID,tgt.NEXT_EVENT_DATE,tgt.CREATED_DATE) VALUES (src.VEHICLE_ID, src.POTENTIAL_EVENT_TYPE_ID, src.CLIENT_ID, src.POTENTIAL_EVENT_DATE, SYSDATE)
;