views:

5364

answers:

5

In Oracle 10g, I have this SQL:

select dog.id as dogId from CANINES dog order by dog.codename asc

which returns:

id
--
204
203
206
923

I want to extend this query to determine the oracle rownum of a dog.id in this resultset.

I have tried

select rownum from 
(select dog.id as dogId from CANINES dog order by dog.codename asc) 
where dog.id=206

But this does not work out very well (it returns 1 no matter which dog.id I match on). I was expecting to get back 3.

Thanks for your help!


Notes

http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html

I am pretty sure I do not need to use rowid

+2  A: 

If you're after the unique identifier of each row in the table you need ROWID, not ROWNUM.

ROWNUM is a pseudocolumn that can change each time a bit of SQL is executed (it's worked out at query time)

cagcowboy
I want to know the sorted row number for a given id in my query, so I guess I want rownum. Thanks.
jedierikb
Seriously, stick to the OP. You can answer what you wanted them to ask after you deal with the OP.
A: 

Use this query:

select rownum2 from ( select dogid as dogId, rownum rownum2 from ids dog order by dogname asc) where dogid =206;

That will return the rownumber of dogid 206, which is 3.

Edwin
I think your query is identical to the query I posted in my question. I just double checked running it... it always returns "1" regardless of which dogid I use in where clause.
jedierikb
yes I noticed. I changed the query to what I meant.
Edwin
You cannot assign the ROWNUM at the same level that the ORDER BY appears. ROWNUM is assigned before the ORDER BY is applied. So this query is applying the rownum as the data is fetched in no particular order, then orders the result by dogname.
Justin Cave
A: 

See if this works for you:

Answer

SELECT dog1.DogID, dog1.DogName, COUNT(*) AS rownumber
FROM #ids dog1, #ids dog2
WHERE dog2.DogName <= dog1.DogName
GROUP BY dog1.DogID, dog1.DogName
ORDER BY dog1.DogName

Results

DogID       DogName    rownumber
----------- ---------- -----------
204         Dog 1      1
203         Dog 2      2
206         Dog 3      3
923         Dog 4      4

DDL

CREATE TABLE #ids (DogID int NOT NULL PRIMARY KEY, DogName varchar(10) NOT NULL)
INSERT INTO #ids (DogID, DogName) VALUES (204, 'Dog 1')
INSERT INTO #ids (DogID, DogName) VALUES (203, 'Dog 2')
INSERT INTO #ids (DogID, DogName) VALUES (206, 'Dog 3')
INSERT INTO #ids (DogID, DogName) VALUES (923, 'Dog 4')
beach
Regrettably, I cannot substantively change my original query (as you do in your answer) because it is auto-generated by another process.
jedierikb
Ah, then this approach will not work. But you should be able to use the "rownum" feature in Oracle to get the same pseudo rownumber.
beach
You can do the same thing much easier in Oracle."select dogID, DogName, rownum from #ids order by DogName" returns the same result as the group-by query, but will perform much better.
Edwin
@Beach, are you a long time SQL Server or MySql guy? I believe they didn't have rownum until recently. Hitting the table twice is a huge performance hit compared with just once.
@Mark True, I primarily use MSSQL. But I also try and use ANSI-standard SQL when possible. "rownum" is not portable. The hit may not be that big depending on how many rows there are and if the table is properly indexed.
beach
+4  A: 

I suspect what you want is to use an analytic function (RANK, DENSE_RANK, or ROW_NUMBER), i.e.

SELECT rnk
  FROM (select dog.id as dogId,
               ROW_NUMBER() OVER( ORDER BY dog.codename ASC ) rnk
          from CANINES dog )
 WHERE dogId = 206

If the ID column in the CANINES table were not unique, RANK, DENSE_RANK, and ROW_NUMBER) would treat ties differently.

If you want to do this solely with ROWNUM,

SELECT rn
  FROM (
        SELECT dogId, rownum rn
          FROM (select dog.id as dogId
                  from CANINES dog 
                 order by dog.codename ASC) inner
       ) middle
 WHERE dogId = 206
Justin Cave
A: 

your query is :: select rounum from cannies dog where dog_id=206;

the ans is 1 becoz... it first create the virtual table with the condition in where clause... we have only one record in the table with the matching of where clause.. so,one record is coming..then rownum is assigned for the rows in the virtual table.. for the qualifying record rownum is 1...so,ans is 1..not 3.

pushpa G.