Your first query works because you have the correct analytic function and you selected a column (actually a pseudo-column) that guaranteed to be unique within a table. The second fails for three reasons.
The first is a simple syntax error; the alias table E is not defined therefore the does not parse and an error ORA-00904 is given. I'll assume the proper correction is to define E as the outermost TAB reference, So it statement reads
DELETE FORM TAB E ....
With the syntax corrected we can address the second problem. The problem hare is a misunderstanding of the count analytic function and contains a hint of the third problem to follow. The count function returns a single value for all rows within the partition. Thus with your sample data the sub-select
SELECT COL1, COL2, COUNT(*)OVER(PARTITION BY COL1,COL2) CNT FROM TAB
produces a result set of:
7839 KING 3
7839 KING 3
7839 KING 3
Not a you seem to expect7839 KING 1
7839 KING 2
7839 KING 3
However the row_number analytic function produces that exact result. So correcting that brings us to a final potential query that reads:
delete from tab e

where ( col1, col2 )

in( select col1, col2

from ( select col1, col2,

row_number ()

over( partition by col1, col2 order by null ) cnt

from tab ) t

where e.col1 = t.col1 and e.col2 = t.col2 and cnt <> 1 );
Now we can address the third ( and fatal ) problem with the original. The problem the above query, accompanied by your own description ,shows is very, very , very common to those use to procedure type languages (such as Java, C++, C#, VB, etc) when they use SQL (which is a declarative language)

For SQL this common base problem is thinking procedurally vs set operation. This is apply demonstrated in your description by the

by the repeated phase 'time of deletion ... my inner query'. This is procedural in that it compares the 1st row from the outer to the first row to the inner, the second row of the outer to 2nd row of the inner, etc. This in NOT what happens.
Each sub-select produces a a result set , this result set is then logically replaces the 'select' and each entry is then applied to each possibility in the outer set. In short you must completely resolve the inner most sub-select, then the next inner most using that result set a,d so on until all have been resolved (This is not necessarily the physical process Oracle or any other relational database uses; it is however the logical process they all use). Using this the above query works out to:
The inner most sub-select:
select col1, col2, row_number () over( partition by col1, col2 order by null ) cnt from tab ) t produces the three row result set7839 KING 1
7839 KING 2
7839 KING 3
The next most outer subsetselect col1, col2

from ( THE PRIOR RESULT SET ) select col1, col2,

where e.col1 = t.col1 and e.col2 = t.col2 and cnt <> 1 )

Since it's correlated it brings in values from the 'select' in this case the delete) but they are used ONLY

for selection determination of the result set for this sub-query.
produces a two row result set7839 KING7839 KING
The final 'select' ( the delete ) now processes as
delete from tab e

where ( col1, col2 ) in ( THE PRIOR RESULT SET ) ;
Since ALL rows in the table having 7839, KING in col1, col2 match at least ONE of the criteria from the prior result set, All rows containing 7839,KING are removed from the table.
By the same process your first query ( rewritten for the same TAB and col1, col2delete from tab
where rowid in( select rowId

from ( select rowid r , row_number( )

over( partition by col2, col1 order by null ) id

from tab ) T

where id <> 1 );
breaks down to:
select rowid r , row_number( ) over( partition by col2, col1 order by null ) id from tabproduces result set
AAAEdiAAEAAAAQeAAD,1
AAAEdiAAEAAAAQeAAF,2
AAAEdiAAEAAAAQeAAE,3
select rowid from POIOR RESULT SET) where id <> 1produces result setAAAEdiAAEAAAAQeAAF,2
AAAEdiAAEAAAAQeAAE,3
delete from tab where row_is in (PRIOR RESULT SET) ;Since rowid in unique the two specified rows are deleted. (If you try this your actual rowids will be different, but the logical process identical)
I hope you to understand why your second query didn't work and also how to analyze what happens with queries and sub-queries.
Belayer

You seem to be assuming that a single DELETE statement will loop and test each time: executing and deleting one row at a time until there are no more duplicates.
I think you've misunderstood how Oracle operates. Oracle takes a snapshot of the table at the start of the DELETE statement, identifies every row that has 1 or more copies, and delete ALL rows.
It will eliminate duplicates and originals.
Try it. It will delete all 3 (7839, KING) rows.
<PRE>
SQL> select * from tab;

You are assuming that Oracle processes the DELETE as a loop, testing the condition <>1 each time, until no more rows meet the condition.
Instead, Oracle takes a snapshot of the table at the start of the SQL statement, and operates on that set of rows. It eliminates the rows that meet the condition.
Otherwise, an INSERT statement like this:
INSERT INTO TAB SELECT * FROM TAB;
would run forever. It doesn't.

10
19 rows selected.
SELECT ename from EMP a WHERE ROWID > (SELECT min(rowid) from emp aa where
aa.ename = a.ename and aa.sal = a.sal);
ENAME
----------
BBB
AAA
BBB
Please note that you must specify all of the columns that make the row a
duplicate in the SQL where clause. Once you have detected the duplicate
rows, you may modify the SQL statement to remove the duplicates as follows:
delete from EMP a WHERE ROWID > (SELECT min(rowid) from emp aa where
aa.ename = a.ename and aa.sal = a.sal);
3 rows deleted.
SQL> select * from emp;