sql query help me with correct update statement [duplicate] - oracle

This question already has an answer here:
Update query resulting wrongly
(1 answer)
Closed 8 years ago.
I have table name emp with 3 columns empid, datof birth, doj
There is an another table test, it has 2 columns empid date of birth. The employee id is the same in both tables.
My requirement is in emp table for some employees in dateofbirth (dob) column who is haveing date '01/05/2011' has to be updated by the dob in table 2 (test)
I need a update statement.
I have joined the query I got some records now I need to replace employees dob in table1 with date dob of same employee from table 2 (test)

Oracle does not support JOIN query directly with UPDATE Statement...
A workaround would be like this:
UPDATE
(SELECT emp.dob AS emp_dob, test.dob AS test_dob
FROM emp
INNER JOIN test
ON emp.empid = test.empid
) tbl
SET tbl.emp_dob = tbl.test_dob

Related

How to solve this Oracle SQL issue? [duplicate]

This question already has answers here:
How to use the 'as' keyword to alias a table in Oracle?
(2 answers)
Closed last year.
select * from(select e.*,dense_rank() over(partition by dept_name order by salary desc) as Top_salaried
from employee e) as B where Top_salaried <= 3;
I have the above query that fetches top 3 salary from each dept
above is working fine PostgreSQL
when i try to exec the same in oracle it throws error
SQL command not properly ended
Can anyone please help me with this
how do i need to modify it in oracle
In Oracle, table aliases don't allow the AS keyword (but column aliases do, such as as top_salaried). So:
SELECT *
FROM (SELECT e.*,
DENSE_RANK ()
OVER (PARTITION BY dept_name ORDER BY salary DESC) AS top_salaried
FROM employee e) b --> no "as" here
WHERE top_salaried <= 3;

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

Oracle Comma Separated Value (ID) in a Column. How to get Description for each Value in a Comma Separated string.

Sorry for the Confusing title.I myself did not understand it when i read it second time.
So here is the details description.
I have a table say "Awards" which have following Column:
Name,
Amount,
Employee
and Another table "Employee" which have following column:
Emp_Id,
Emp_Name
and in employee column of "Awards" table i have value "01,20" which are actually the Employee ID referenced to "Employee" table.
So is there any way i can get Employee Name in select "Awards" query?
Here is one method:
select a.*, e.EmpName
from Awards a join
Employees e
on ','||a.employee||',' like '%,'||e.emp_id||',%';
This will return the employee names on separate lines. If you want them in a list, then you would need to concatenate them together (and the best function for doing that depends on your version of Oracle).
By the way, this is a very bad data structure, You should have an association table AwardEmployee that has one row for each row and each employee.
Given below is the query to get comma seperated employee ids in form of rows which I put in subquery to get their name. Please edit as per your ewquirements.
Select Ename from employee where employee_id in (
SELECT trim(x.column_value.extract('e/text()')) COLUMNS
from awards t, table (xmlsequence(xmltype('<e><e>' || replace(Employee,':','</e><e>')||
'</e></e>').extract('e/e'))) x )
I have changed the Database (added one more table). and already started changing the CODE, as for the said report i have used following
WITH t AS
(
Select emp_name from employee where emp_id in (
select regexp_substr(Employee ,'[^,]+', 1, level) from awards
connect by regexp_substr((select Employee from awards ), '[^,]+', 1, level) is
not null)
)
SELECT LTRIM(SYS_CONNECT_BY_PATH(emp_name, ','),',') emp_name
FROM ( SELECT emp_name,
ROW_NUMBER() OVER (ORDER BY emp_name) FILA
FROM t )
WHERE CONNECT_BY_ISLEAF = 1
START WITH FILA = 1
CONNECT BY PRIOR FILA = FILA - 1
Which is temporary and i understand very less of it.
Thanks for you help and suggestion.

How to clear table in oracle

I have data table in Oracle 8,1. There are about a million rows. But lots of rows duplicates by the same columns. I need to know fastest way to clear this data.
For example I have:
id name surname date
21 'john' 'smith' '2012 12 12';
21 'john' 'smith' '2012 12 13';
21 'john' 'smith' '2012 12 14';
....
And now I need to delete first two rows as they duplicates by first three columns and keep the row with the latest date.
If there are really lots of duplicates, I'd recommend to recreate the table with only the clean data:
CREATE TABLE tmp AS
SELECT id, name, surname, max(d) as d
FROM t
GROUP BY id, name, surname;
and then replace the original table with the original table:
RENAME your_table TO old_table;
RENAME tmp_table TO your_table;
Don't forget to move indexes, constraints and privileges...
delete from table t where
exists (select * from table where id=t.id and name=t.name and surname=t.surname
and date > t.date)
How fast this is depends con your Oracle parameters. And index on (id,name,surname) might help.
If possible, I'd go for a CTAS (create table as select), truncate the original table, and copy the data back:
-- create the temp table (it contains only the latest values for a given (id, name, surname) triple
CREATE TABLE tmp as
SELECT id, name, surname, date1 from
(select
t1.*,
row_number() over (partition by id, name, surname order by date1 desc) rn
from mytab t1)
where rn = 1;
-- clear the original table
TRUNCATE TABLE mytab;
-- copy the data back
INSERT /* +APPEND */ INTO mytab(id,name,surname,date1)
(SELECT id,name,surname,date1 from tmp);

select rows from third row to n th row in oracle [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Paging with Oracle
I try to select data starting from 11 row. and i used
select e_name from copy where rownum>10;
this will not display's anything..
please help me to select 11th row to 15th row in my table
You cannot use rownum like that, you need to wrap everything into a derived table:
select *
from (
select *,
rownum as rn
form your_table
order by some_column
)
where rn between 11 and 15
You should use an order by in the inner query because otherwise you will not get consistent results over time. Rows in a relational table do not have any ordering so the database is free to return the rows in any order it feels approriate.
Please read the manual for more details. The reason your query isn't working is documented there with examples.
http://docs.oracle.com/cd/E11882_01/server.112/e26088/pseudocolumns009.htm#i1006297
You have to use like
select e_name
from (select e_name,rownum rno from copy)
where rno > 10 and rno < 16
Sample Example
you could use analytic function row_number() as well. Please consider http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions137.htm
First write the query which will select all the rows like this:-
select ename from employee
Now add a rownum column to your query, rownum will help you to identify the number of row in your query result
select rownum r,ename from employee
Now make your query as a sub query and apply the range on 'r' (rownum)
select * from (selecr rownum r, ename from employee) subq where subq.r between 11 and 15

Resources