He probado la siguiente consulta:

select empno from (
                   select empno 
                     from emp
                    order by sal desc
                  )
where rownum = 2

Este no devuelve ningún registro.

Cuando traté de esta consulta

 select rownum,empno from (
                        select empno from emp order by sal desc) 

Me da este resultado:

ROWNUM  EMPNO      
1       7802        
2       7809    
3       7813    
4       7823

¿Alguien puede decirme cuál es el problema con mi primera consulta? Por qué no regresan ningún registro cuando agrego el ROWNUM filtro?

InformationsquelleAutor Gaurav Soni | 2012-02-11

7 Comentarios

  1. 50

    Para explicar este comportamiento, tenemos que entender cómo los procesos de Oracle
    ROWNUM. A la hora de asignar ROWNUM a una fila, Oracle comienza en 1 y
    sólo se incrementa el valor cuando se selecciona una fila; es decir, cuando todos los
    las condiciones en la cláusula where se cumplen. Desde nuestra condición requiere
    que ROWNUM es mayor que 2, no se seleccionan filas y ROWNUM es
    nunca se incrementa más allá de 1.

    La línea de fondo es que las condiciones tales como la siguiente funcionará como
    se esperaba.

    .. DONDE rownum = 1;

    .. DONDE rownum <= 10;

    Mientras que las consultas con estas condiciones siempre se puede volver a cero filas.

    .. DONDE rownum = 2;

    .. DONDE rownum > 10;

    Citado de La comprensión de Oracle rownum

    Debe modificar la consulta de esta manera, en orden de trabajo:

    select empno
    from
        (
        select empno, rownum as rn 
        from (
              select empno
              from emp
              order by sal desc
              )
        )
    where rn=2;

    EDITAR: he corregido la consulta para obtener el rownum después de la orden de sal desc

    • :Gracias por la explicación +1 …la consulta es que no vale la pena, porque quiero que el rownum de los registros obtenidos sobre la base de la orden de sal desc ,la consulta de la fuerza de trabajo si ponemos rownum en el interior de la consulta ,se nos da rownum de los registros de la tabla emp ,no de los datos ordenados….Gracias por la explicación
    • Buena respuesta (+1), pero la consulta que propone no funciona correctamente y regresar el 2º mejor pagado del empleado. Usted necesitará otro nivel de la subconsulta para asegurarse de ROWNUM es asignado después ORDENAR POR.
    • estás en lo correcto. voy a corregir la respuesta
    • Como una pequeña mejora puede reducir el medio de consulta para rownum <= 2. Eso probablemente va a mejorar el rendimiento cuando la tabla es grande. Un problema aquí, sin embargo, es que todavía no encuentra el empleado con el segundo salario más alto. Si hay dos principales empleados tienen el mismo sueldo, esencialmente estamos recogiendo una forma arbitraria… Si realmente queremos que los empleados con el segundo salario más alto necesita hacer una consulta para que las órdenes distintos de los salarios…
    • Oracle siempre optimizar este tipo de consulta. La consulta propuesta por mí va a escanear la tabla emp sólo una vez y, durante la exploración, en la memoria sólo será de dos filas, aquellos con salarios más altos.
    • Es por eso que oracle pagan grandes cantidades de dinero. Ellos son grandes en optimizaciones. A veces en el hecho de tratar de optimizar una consulta hace de oracle más lento debido a que se realiza la consulta demasiado complicado para las optimizaciones automáticas.

  2. 8

    En el primera consulta, la primera fila se han ROWNUM = 1 así, serán rechazados. La segunda fila también se han ROWNUM = 1 (porque la fila antes de que se rechazó) y también ser rechazado, la tercera fila también tendrá ROWNUM = 1 (porque todas las filas antes de que fueran rechazados) y también ser rechazado, etc… El resultado neto es que todas las filas son rechazados.

    La segunda consulta no debe devolver el resultado que obtuvo. Se debe asignar correctamente el ROWNUM después de ORDEN.

    Como consecuencia de todo esto, es necesario utilizar no 2, sino 3 niveles de subconsultas, como este:

    SELECT EMPNO, SAL FROM ( -- Make sure row is not rejected before next ROWNUM can be assigned.
        SELECT EMPNO, SAL, ROWNUM R FROM ( -- Make sure ROWNUM is assigned after ORDER BY.
            SELECT EMPNO, SAL
            FROM EMP
            ORDER BY SAL DESC
        )
    )
    WHERE R = 2

    El resultado:

    EMPNO                  SAL                    
    ---------------------- ---------------------- 
    3                      7813                   
    • +1 para una explicación detallada de la consulta
    • Lástima que esto se hace mucho más complicado cuando se selecciona * en su lugar si usted no desea que el rownum como parte de la salida. Especialmente cuando estamos haciendo un join o consultar una vista.
  3. 1

    intente esto:

    SELECT ROW_NUMBER() OVER (ORDER BY empno) AS RowNum,
           empno
    FROM   tableName
    WHERE  RowNumber = 2;

    Fragmento De Código Fuente:

    SELECT last_name FROM 
          (SELECT last_name, ROW_NUMBER() OVER (ORDER BY last_name) R FROM employees)
    WHERE R BETWEEN 51 and 100

    REFERENCIA

    • :Gracias por la solución ,pero no estoy buscando la solución aquí ,yo estoy buscando la causa por la consulta anterior no funciona ..
    • Cree que su where cláusula debe tener RowNum en lugar de RowNumber
  4. 1

    Por enésima fila usando rownum en oracle:

    select * from TEST WHERE ROWNUM<=n
    MINUS
    select * from TEST WHERE ROWNUM<=(n-1);

    Ejemplo para la segunda fila :

    select * from TEST WHERE ROWNUM<=2
    MINUS
    select * from TEST WHERE ROWNUM<=1;
    • Kamruzzaman : debe haber criterios para recuperar el enésimo récord ,por ejemplo el segundo salario más alto ,no existe lógica en su consulta
  5. 0

    select empno de(

    select empno,rownum como ron

    de emp,

    orden de sal desc

    )

    donde ron=2;

    • Hola Deepak, y bienvenido ENTONCES! Mientras que su respuesta puede ser correcta, ¿cuál es el valor añadido en comparación con la que ya se acepta la respuesta? En mi humilde opinión, su respuesta es redundante y no aporta ninguna información útil. Por lo tanto es poco probable recibir ninguna confirmación positiva. Se centran en preguntas sin respuesta o la adición de respuestas con valor adicional para ganar algo de reputación.
  6. 0
    Select * From (SELECT *,
      ROW_NUMBER() OVER(ORDER BY column_name  DESC) AS mRow
    
    FROM table_name 
    
    WHERE condition) as TT
    Where TT.mRow=2;
  7. -1

    Puede utilizar RANK o DENSE_RANK para lograr lo que usted está tratando de lograr aquí.

    • usted debe proporcionar un ejemplo

Dejar respuesta

Please enter your comment!
Please enter your name here