2010-08-10 19 views
180

¿Cómo hago lo siguiente?¿Cómo hago la parte superior 1 en Oracle?

select top 1 Fname from MyTbl 

En Oracle 11g?

+0

Tener un vistazo a [¿Cómo se puede seleccionar las filas TOP N de una tabla] (http://www.orafaq.com/faq/how_does_one_select_the_top_n_rows_from_a_table) –

+0

posible duplicado de [¿Cómo puedo limitar el número de filas devueltas por una consulta de Oracle después de ordenar?] (Http://stackoverflow.com/questions/470542/how-do-i-limit-the-number-of-rows -returned-by-a-oracle-query-after-ordering) –

+3

¿Puede decirnos el orden según el cual usted nt 'top 1'? –

Respuesta

199

Si sólo desea una primera fila seleccionada, puede:

select fname from MyTbl where rownum = 1 

También puede utilizar las funciones analíticas para ordenar y tomar la x alto:

select max(fname) over (rank() order by some_factor) from MyTbl 
+6

No estoy seguro de qué se supone que debe lograr el segundo ejemplo ... –

+38

Esto es bueno si solo quieres 1 fila y no te importa. Si desea filas específicas, como el registro más reciente, debe hacer el ordenamiento en una subselección, como la respuesta de Vash. Oracle asigna rownums antes del género. –

+3

@Scott yup. eso es correcto. Y Patrick, buen punto, creo que la sintaxis es incorrecta en eso. Realmente debería ser un recordatorio (dense_rank() último ...) – mcpeterson

4
select * from (
    select FName from MyTbl 
) 
where rownum <= 1; 
125
SELECT * 
    FROM (SELECT * FROM MyTbl ORDER BY Fname) 
WHERE ROWNUM = 1; 
+5

Esta respuesta recibe correctamente la fila TOP (ordena los resultados antes de restringir en ROWNUM). – JulesLt

+0

Esta respuesta no es una traducción exacta: la consulta original no tiene un ORDER BY ni devuelve todas las columnas de la tabla. –

+0

Estoy parado (ver a continuación). Cambiará los votos una vez que se acabe el tiempo. – JulesLt

5

Uso:

SELECT x.* 
    FROM (SELECT fname 
      FROM MyTbl) x 
WHERE ROWNUM = 1 

Si usa Oracle9i +, puede mirar using analytic functions like ROW_NUMBER() but they won't perform as well as ROWNUM.

+1

Buena respuesta, pero contiene un pequeño error tipográfico.¿Dónde dices que Oracle9i + no debería ser 8i? http://download-west.oracle.com/docs/cd/A87860_01/doc/server.817/a76994/analysis.htm#11237 –

+0

@carpenteri: Cierto, los análisis estaban disponibles en 8i - no recuerdo los detalles de , pero los análisis no estaban realmente disponibles para el público hasta el 9i. –

+0

Comentario pequeño: la respuesta de Vash a continuación incluye un ORDER BY en la consulta interna que es crítico si desea el valor TOP de fname, en lugar de 'first' (que puede ser cualquier cosa, muy probablemente la primera fila insertada). ¿Valdría la pena editarlo? – JulesLt

2

que tenían el mismo problema, y ​​puedo solucionar este problema con esta solución:

select a.*, rownum 
from (select Fname from MyTbl order by Fname DESC) a 
where 
rownum = 1 

Puede pedir que su resultado antes de tener el primer valor en la parte superior.

Buena suerte

6

Usted puede hacer algo como

SELECT * 
     FROM (SELECT Fname FROM MyTbl ORDER BY Fname) 
WHERE rownum = 1; 

También es posible usar las funciones analíticas RANK y/o DENSE_RANK, pero ROWNUM es probablemente el más fácil.

+1

puede por favor ayudar con algún ejemplo de rango, etc. – breakfreehg

3

Seleccionar la primera fila de una tabla y seleccionar una fila de una tabla son dos tareas diferentes y necesita una consulta diferente. Hay muchas maneras posibles de hacerlo. Cuatro de ellos son:

Primera

select max(Fname) from MyTbl; 

Segunda

select min(Fname) from MyTbl; 

Tercer

select Fname from MyTbl where rownum = 1; 

Cuarta

select max(Fname) from MyTbl where rowid=(select max(rowid) from MyTbl) 
19

Con Oracle 12c (junio de 2013), puede usarlo de la siguiente manera.

SELECT * FROM MYTABLE 
--ORDER BY COLUMNNAME -OPTIONAL   
OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY 
+6

Interesante comando, estoy usando 12c aquí y el 'OFFSET 0 ROWS' aparentemente no es necesario, puede usar' FETCH NEXT 1 ROWS ONLY' o incluso 'FETCH FIRST ROW SOLO', el orden por es importante o será equivalente a simplemente usar un 'WHERE rownum = 1'. Incluso lo intenté en una instrucción APLICACIÓN EXTERNA y funcionó como la función TOP de Ms-SQL allí. –

+0

Tienes razón @RafaelMerlin. Después de su publicación, reconocí que OFFSET 0 ROWS no es necesario. Sería útil al recuperar datos entre X superior y Y superior. – MSK

+0

Más ejemplos: https://oracle-base.com/articles/12c/row-limiting-clause-for-top-n-queries-12cr1 – FixFaier

8

Usted podría utilizar ROW_NUMBER() con una cláusula ORDER BY en sub-consulta y utilizar esta columna en sustitución de TOP N. Esto se puede explicar paso a paso.

Consulte la tabla a continuación que tiene dos columnas NAME y DT_CREATED.

enter image description here

Si tiene que tomar sólo las dos primeras fechas, independientemente de NAME, se puede utilizar la siguiente consulta. La lógica se ha escrito en su interior consulta

-- The number of records can be specified in WHERE clause 
SELECT RNO,NAME,DT_CREATED 
FROM 
(
    -- Generates numbers in a column in sequence in the order of date 
    SELECT ROW_NUMBER() OVER (ORDER BY DT_CREATED) AS RNO, 
    NAME,DT_CREATED 
    FROM DEMOTOP 
)TAB 
WHERE RNO<3; 

RESULTADO

enter image description here

En algunas situaciones, tenemos que seleccionar TOP N resultados respectivos a cada NAME. En tal caso, podemos usar PARTITION BY con una cláusula ORDER BY en la subconsulta. Consulte la consulta a continuación.

-- The number of records can be specified in WHERE clause 
SELECT RNO,NAME,DT_CREATED 
FROM 
(
    --Generates numbers in a column in sequence in the order of date for each NAME 
    SELECT ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY DT_CREATED) AS RNO, 
    NAME,DT_CREATED 
    FROM DEMOTOP 
)TAB 
WHERE RNO<3; 

RESULTADO

enter image description here

+0

Uso de ROW_NUMBER() ... es una solución más correcta que en la respuesta al tema. Un problema con esta solución (y con la variante máxima (campo) también) de que no se pueden hacer cosas como "seleccionar ... (seleccionar ROW_NUMBER() ...) ** para la actualización **;" –

+0

Y a veces es muy importante en PL/SQL (lo siento, no se pudo editar el comentario anterior en el límite de 5 minutos). –

+0

En tal caso, podemos usar CTE como en la parte exterior. ¿Derecha? @Alexo Po. –

Cuestiones relacionadas