0

Suppose I have a table with column A like following :

a  
--
x  
y  
m  
x  
n  
y  

I want to delete all rows that have duplicate a column value and keep just one value. After this operation, my column would be like If you do :

select distinct a from A;

I know how to select rows with repeated a column values But I can't just replace select with DELETE because it would delete the unique values too.
Any help would be greatly appreciated.

2
  • which dbms ar u using , SQL Server or MySql ? Commented Mar 20, 2014 at 11:50
  • Oracle 9i :) Sorry I've just edited the tags ;) Commented Mar 20, 2014 at 11:52

3 Answers 3

3

In Oracle, you can do this by using the hidden column rowid and a correlated subquery:

delete from a
    where rowid > (select min(rowid)
                   from a a2
                   where a.a = a2.a
                  );

Alternatively, you can phrase this as a not in:

delete from a
    where rowid not in (select min(rowid)
                        from a a2
                        group by a2.a
                       );
Sign up to request clarification or add additional context in comments.

6 Comments

two rows in my table A with repeated column a values have not necessarily the same ROWID, only column a may be repeated, but other columns may have different values @Gordon Linoff
is there a way to delete in oracle using cte like mssql server ?
@mhasan . . . Oracle does not support CTEs with the delete statement, so there is no way to do that.
@mounaim . . . I don't understand your comment. This is how you delete rows in a table in Oracle so you only keep one value. In Oracle, two rows necessarily have different ROWID.
Could someone please explain clearly how ROWID works in Oracle ?
|
1

You can use combination of CTE and Ranking function

;With cte As
(
Select ROW_NUMBER() OVER (PARTITION BY colA ORDER BY colA) as rNum
From yourTable 
)

Delete From cte
Where rNum<>1

5 Comments

I think I understand your strategy here but what is the meaning of the 'PARTITION BY' 'WITH CTE AS' clauses @m hasan ?
Partition By Clause divides the column values into subsets acording to the column values and the ORDER BY clause the assigns rank to member of each subset.
Yes I understand now this (docs.oracle.com/cd/B19306_01/server.102/b14200/functions137.htm) But I'm getting this error : ORA00923 "FROM keyword not found where expected" in my case (Oracle 9i) Have you already had this error @m hassan ?
Strangely , oracle doesnot seem to support deletion by using common table expression , unlike MS SQL Server... you should go by Gordon Linoff solution .. his solution fiddle is here ...sqlfiddle.com/#!4/2d187/16
Ok Thank you m hassan for information :) I've already commented to Gordon Linoff why his solution wouldn't work for me because my rows with repeated column a values aren't having the same ROWID
0

In SQL, You can use CTE and delete the duplicated rows. See the query below.

WITH CTE AS(
   SELECT a,
       RN = ROW_NUMBER()OVER(PARTITION BY a ORDER BY a)
   FROM A
)
DELETE FROM CTE WHERE RN > 1

1 Comment

Wow! I didn't know you could CTEs with delete in Oracle. Can you provide some documentation on this? It returns an error in this simple SQL Fiddle: sqlfiddle.com/#!4/b9bb1/1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.