2012-03-13 16 views
6

Tengo la siguiente consulta:¿Por qué el operador = no funciona con ROWNUM aparte del valor 1?

select * from abc where rownum = 10 

salida: No hay registros que mostrar

estoy seguro que tengo más de 25 registros en la tabla abc y mi objetivo es mostrar el registro de orden n.

Si escribo la consulta como: -

select * from abc where rownum = 1 

que trabaja muy bien y me da el primer registro. Ningún otro registro que no sea el primero.

¿Alguna idea?

Respuesta

18

Porque los números de fila se asignan secuencialmente a las filas que se obtienen y devuelto.

Así es como funciona tu afirmación. Toma la primera fila de candidatos y le da temporalmente la fila número 1, que no coincide con su condición, por lo que se descarta.

Luego obtiene la segunda fila de candidato y es también la fila número 1 (ya que la anterior fue arrojada). No coincide tampoco.

Luego, la tercera fila de candidatos ... bueno, estoy seguro de que puede ver a dónde va esto ahora. En resumen, nunca encontrarás una fila que satisfaga esa condición. Los números de fila solo son útiles para = 1, < something o <= something.

Todo esto se explica en el Oracle docs for the rownum pseudo-column.

También debe tener en cuenta que SQL es un álgebra relacional que devuelve conjuntos desordenados a menos que especifique un pedido. Eso significa que la fila número diez puede ser algo ahora y algo más en tres minutos.

Si desea una forma (kludgy, es cierto) para obtener el n ª fila, se puede usar algo como (para la quinta fila):

select * from (
    select * from (
     select col1, col2, col3 from tbl order by col1 asc 
    ) where rownum < 6 order by col1 desc 
) where rownum = 1 

El seleccione interior se asegurará de que tiene un orden coherente en la consulta antes de comenzar a tirar filas, y la selección del medio descartará todas las primeras cinco filas excepto las primeras, y también revertirá el orden.

La selección externa solo devolverá la primera fila del conjunto invertido (que es la última fila del conjunto de cinco filas cuando estaba en orden ascendente).

Una mejor manera es probablemente:

select * from (
    select rownum rn, col1, col2, col3 from tbl order by col1 
) where rn = 5 

Esto funciona mediante la recuperación de todo y la asignación de la rownum a una columna de "real", y luego usar ese número real de columna para filtrar los resultados.

+0

Muchas gracias. ¿Puedes sugerir alguna alternativa para cumplir mi objetivo? Es decir, mostrar el n-ésimo registro si sé el valor de n? –

+0

Muchas gracias.El documento de Oracle dice esto: ACTUALIZAR my_table SET column1 = ROWNUM; Será mejor tener una columna real en la tabla y luego filtrar el resultado con eso. :) –

+1

@SaharHassan, el único problema con eso es que necesitas mantenerlo. En otras palabras, es probable que deba tener activadores o una columna de incremento automático. Pero nada de eso ayuda con el hecho de que los conjuntos de resultados son intrínsecamente poco originales, a menos que usted los ordene explícitamente. – paxdiablo

Cuestiones relacionadas