Update a column of table with ROW_NUMBER - oracle

I am new to Oracle I need to Update a Column of a Table with ROW_NUMBER() in oracle
i.e
UPDATE tablefull
SET newcolumn=ROW_NUMBER() OVER (PARTITION BY columnid ORDER BY datecolumn)-1
Since the Window function is not allowed in Update I had tried with joining the table with subquery of same table and do the update
update a
set a.newcolumn= b.upnum
from tablefull a
INNER JOIN (SELECT columnid,ROW_NUMBER() OVER (PARTITION BY columnid ORDER BY datecolumn)-1 AS upnum
FROM tablefull) b ON b.columnid=a.columnid
Since the join and update is also not possible in oracle the above also did not worked out
Please anyone help me in the way to update the newcolumn of the table with ROW_NUMBER() OVER (PARTITION BY columnid ORDER BY datecolumn)-1 in Oracle

Put this query with row_number as source table of merge statement:
merge into tablefull tgt
using (select rowid rwd, columnid,
row_number() over (partition by columnid order by datecolumn) - 1 rn
from tablefull) src
on (src.rwd = tgt.rowid and tgt.columnid = src.columnid)
when matched then update set newcolumn = rn;
dbfiddle

Related

how to use rownumber over partition in ODI MAPPING

My requirement is to get the recent record grouped by columns c1,c2.I have 50 columns in my source, using query i can apply rownumber() over partition by c1,c2 order by record_time desc, and pick the record where rownumber=1. In short, my oracle query would be:
select c1,c2,....,c50
from (select c1,c2,....,c50,
row_number() over (partition by c1,c2 order by record_time desc ) rn
from table)
where rn = 1;
How can I achieve this using ODI mapping? Please suggest.
Thanks
You have not mentioned the version of ODI you are using, assuming you are using ODI 11g. You can create a yellow interface and create a column for rownum with expression as below
row_number() over (partition by c1,c2 order by record_time desc)
Now use this yellow interface as source in your interface and apply filter on rownum column as below
rownum = 1
While using this you will have to make sure your KM is not adding group by function, else it'll end up in error.

How to find record from a very big HIVE table where column header__timestamp,header__change_seq should be latest update and id should unique

I have to find record from the hive table where Id, der__timestamp, header__change_seq should be unique but in table (Id, der__timestamp, header__change_seq) can duplicate so in this case i have to fetch only one record if records are getting duplicate .
select b.*
from (SELECT ID, max(COALESCE(header__timestamp))
max_modified,MAX(CAST(header__change_seq AS DECIMAL(38,0))) max_sequence
FROM table_name group by ID) a
join table_name b on (a.id=b.id and
a.max_modified=b.header__timestamp and
a.max_sequence=b.header__change_seq)
So the total number of distinct id is count-->244441250
but through above query i am getting count-->244442548
due to some duplicate records but i have to find only distinct id where (header__change_seq and header__timestamp) should max .
#Rahul; please try this one. It makes use of row_number() so in case of duplicate id, header_timestamp and hearder_change_seq, it will select only one record. Hope it helps.
select *
from (
select *,
row_number() over ( partition by id order by header__timestamp desc, header__change_seq desc) as rnk
from table_name) t
where t.rnk = 1;

Getting Error "ORA-01732: data manipulation operation not legal on this view" while deleting from a table in oracle

Same query running in Db2 , but in oracle it's giving error.
Please help. thanks in advance.
delete from (SELECT
EMP_ID,
SAL,
ROW_NUMBER() OVER (PARTITION BY EMP_ID ORDER BY SAL DESC) As RN
FROM FPM.FACT_PL_BS
WHERE MEASUREMENT_PERIOD_ID=20170811
AND SCENARIO_ID=1) A where RN>1}
Check documentation Notes on Updatable Views:
The view must not contain any of the following constructs:
A set operator
A DISTINCT operator
An aggregate or analytic function
A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
A collection expression in a SELECT list
A subquery in a SELECT list
A subquery designated WITH READ ONLY
Joins, with some exceptions, as documented in Oracle Database Administrator's Guide
ROW_NUMBER is an Analytic Function, so update is not permitted.
I think this one should work (not tested):
delete from FPM.FACT_PL_BS
WHERE ROWID =ANY
(SELECT ROW_ID
FROM
(SELECT ROWID as ROW_ID,
EMP_ID,
SAL,
ROW_NUMBER() OVER (PARTITION BY EMP_ID ORDER BY SAL DESC) As RN
FROM FPM.FACT_PL_BS
WHERE MEASUREMENT_PERIOD_ID=20170811
AND SCENARIO_ID=1)
WHERE RN > 1;
or maybe
delete from FPM.FACT_PL_BS
WHERE MEASUREMENT_PERIOD_ID=20170811
AND SCENARIO_ID=1
AND ROWID <>ALL
(select MAX(ROWID) KEEP (DENSE_RANK FIRST ORDER BY SAL) OVER (PARTITION BY EMP_ID)
FROM FPM.FACT_PL_BS)

Cannot delete from view without exactly one key-preserved table workaround

I have a table x_visa. I want to delete the duplicate columns from this table.
The query I am using for this is :
select * from (SELECT x_visa.*,
ROW_NUMBER() over (partition by effective_start_date, effective_end_date, person_id,
business_group_id, legislation_code , current_visa_permit, visa_permit_type, visa_permit_id, configuration_id
order by person_id) AS rn
from x_visa) T
WHERE rn > 1 );
The delete statement is giving an error :ORA-01752: cannot delete from view without exactly one key-preserved table
delete from
(select * from (SELECT x_visa.*,
ROW_NUMBER() over (partition by effective_start_date, effective_end_date, person_id,
business_group_id, legislation_code , current_visa_permit, visa_permit_type, visa_permit_id, configuration_id
order by person_id) AS rn
from x_visa) T
WHERE rn = 1 );
Is there a workaround to delete the duplicate data from this table ?
Each row has rowid identifier. So you can delete where rowid in results of your query.
delete from x_visa where rowid in (/*YOUR QUERY*/);
So we have:
delete from x_visa where rowid in (select r from (SELECT x_visa.rowid r, x_visa.*,
ROW_NUMBER() over (partition by effective_start_date, effective_end_date, person_id,
business_group_id, legislation_code , current_visa_permit, visa_permit_type, visa_permit_id, configuration_id
order by person_id) AS rn
from x_visa) T
WHERE rn > 1 ))

Oracle update query to update records in sequential order

I have a table in Oracle SQL whose ids are in increasing, sequential order, but there are gaps in the ids due to editing, e.g. the ids are currently something like
22
23
24
32
33
44
...etc
I check one post and the solution provided was as below:
update (select t.*, row_number() over (order by id) as newid) toupdate
set id = newid
Solution Provided earlier.
Now my query:
1) I guess the "From clause" is missing in the above query.
Updated query:
update (select t.*,
row_number() over (order by emp_id) as newid
from employee t ) toupdate
set emp_id = newid;
2) When i run the above query, it gives me error "data Manipulation operation not legal on this view".
Can anyone explain how the mentioned solutions worked here. can anyone post the full update query. Thanks.
This solution to the same question you referenced shows how to do it:
update employee set emp_id = (
with tab as (
select emp_id, rownum r
from (select emp_id from employee order by emp_id)
)
select r from tab where employee.emp_id = tab.emp_id
);
That works. You cannot update a view that contains an analytic function like row_number - see Oracle 12C docs, look for "Notes on Updatable Views".
You could use a merge, but you'd need to join on something other than emp_id as you want to update that column. If there are no other unique columns you can use the rowid:
merge into employee target
using (select rowid, row_number() over (order by emp_id) as emp_id from employee) source
on (source.rowid = target.rowid)
when matched then update set target.emp_id = source.emp_id;
I think this would be easiest approach :
update mytable set id = ROWNUM;
Oracle SQL - update ids in oracle sql to be in sequential order

Resources