¿Cómo seleccionar solo 1 fila de Oracle SQL?

110

Quiero usar la sintaxis de Oracle para seleccionar solo 1 fila de la tabla DUAL. Por ejemplo, quiero ejecutar esta consulta:

SELECT user 
  FROM DUAL

... y tendría como 40 registros. Pero solo necesito un registro. ... Y quiero que suceda sin una WHEREcláusula.

Necesito algo en el campo table_name como:

SELECT FirstRow(user) 
  FROM DUAL
Ben
fuente
1
¿Qué versión de Oracle? Usar ROWNUM o ROW_NUMBER (9i +) significaría necesitar una cláusula WHERE
OMG Ponies
1
¿Nombraste una mesa dual?
ypercubeᵀᴹ
1
@ypercube duales la tabla del sistema en
4
@Ben, realmente no deberías crear una tabla llamada DUAL. Es un poco como #define TRUE 0en C: seguro, podría funcionar para usted, pero los futuros desarrolladores lo odiarán.
Jeffrey Kemp
3
¿De verdad has intentado correr select user from dual? Si no es así, inténtelo y vea lo que obtiene. En un sistema Oracle estándar, recuperará el usuario con el que está ejecutando el comando.
Shannon Severance

Respuestas:

169

Usas ROWNUM.

es decir.

SELECT user FROM Dual WHERE ROWNUM = 1

http://docs.oracle.com/cd/B19306_01/server.102/b14200/pseudocolumns009.htm

Mindvirus
fuente
@ypercube por lo que puedo decir, lo hace. (Al menos funciona para mi instalación de oracle10g.)
@bdares: funcionará, sí. Pero no tu respuesta, con el order by.
ypercubeᵀᴹ
1
Si. ROWNUM es una columna especial que se agrega al conjunto de resultados que enumera los resultados. También puede usarlo para seleccionar varios, por ejemplo, si desea encontrar los 10 empleados mejor pagados, podría decir "SELECCIONAR usuario DE Empleados DONDE ROWNUM <= 10 ORDEN POR
SALARIO DESCENDENTE
10
@mkdess: No, ORDER BYse aplica después de WHERE.
ypercubeᵀᴹ
15
Necesitarías:SELECT * FROM (SELECT user FROM Employees ORDER BY SALARY DESC) WHERE ROWNUM <= 10
ypercubeᵀᴹ
49

Encontré esta "solución" oculta en uno de los comentarios. Como lo estuve buscando por un tiempo, me gustaría resaltarlo un poco (aún no puedo comentar o hacer esas cosas ...), así que esto es lo que usé:

SELECT * FROM (SELECT [Column] FROM [Table] ORDER BY [Date] DESC) WHERE ROWNUM = 1

Esto me imprimirá la entrada de [Columna] deseada de la entrada más reciente en la tabla, asumiendo que [Fecha] siempre se inserta a través de SYSDATE.


fuente
Descubrí que también funcionará si realiza el pedido ROWID, siempre que nunca elimine ningún registro y siempre se preocupe por el último insertado / modificado.
vapcguy
@vapcguy: ¡No espere que se ordene ROWID, incluso si nunca elimina una fila de la tabla! Incluso si funciona para usted ahora, nunca se garantiza que funcione en versiones futuras.
D. Mika
@ D.Mika En realidad, si funciona ahora y nunca agrega / elimina / actualiza / elimina registros, nunca debería haber ningún problema. Los registros solo se pueden cambiar si realmente los cambia. Existe esta idea errónea de que de alguna manera ROWIDOracle lo modifica aleatoriamente. No lo es. Se basa en modificar realmente las filas, es decir, borra una y luego inserta una. El insertado obtendrá el anterior ROWID. Hay cosas como tablas estáticas que nunca se actualizan, como los estados en los EE. UU. Es un buen ejemplo, donde si cambia, probablemente tendría otras repercusiones, de todos modos, cuando esto está bien.
vapcguy
@vapcguy: Bueno, eso es casi correcto. Pero hay otras operaciones que cambiarán el ROWID. ¿Qué pasa si exporta / importa la tabla por algún motivo? Hay otras operaciones, pero algunas necesitan HABILITAR MOVIMIENTO DE FILA. Solo quiero decir que no es buena idea depender de un detalle de implementación que pueda cambiar en el futuro.
D. Mika
@ D.Mika Estoy seguro de que si hay alguna operación en la ROWIDque se pueda cambiar, un buen administrador de base de datos los buscaría y haría lo que pudiera para evitarlos si existiera la posibilidad de que estuvieran afectando una tabla estática como la que describí. solo la aplicación debería estar funcionando. En su lugar, se puede realizar una exportación de tabla con una SELECTdeclaración. La importación ocurriría una vez y nunca más. Entiendo su punto, definitivamente se necesita cuidado, pero los problemas están lejos de ser inevitables.
vapcguy
35

Esta sintaxis está disponible en Oracle 12c:

select * from some_table fetch first 1 row only;
select * from some_table fetch first 1 rows only;
select * from some_table fetch first 10 row only;
select * from some_table fetch first 10 rows only;

^^ Solo quería demostrar que se pueden usar filas o filas (plural) independientemente de la pluralidad del número deseado de filas).

mancini0
fuente
1
seleccionar * de some_table buscar solo la primera fila; no funciona en mi devloper swl ni en sql plus, por lo que hay un error al buscar.
nikhil sugandh
¿Está utilizando Oracle 12c?
mancini0
Realmente no lo sé, pero cuando lo abro se muestra así: SQL * PLus Release 10.1.0.4.2 no es 12 c
nikhil sugandh
correcto: probablemente esté usando la versión 10.1.xxx, puede SELECCIONAR * DE V $ VERSION
mancini0
10

tenemos 3 opciones para obtener la primera fila en la tabla Oracle DB.

1) select * from table_name where rownum= 1es la mejor manera

2) select * from table_name where id = ( select min(id) from table_name)

3)

select * from 
    (select * from table_name order by id)
where rownum = 1
Deva
fuente
Gracias por las respuestas: en el punto 3) "nowrum = 1" probablemente debería cambiarse a "rownum = 1".
Andre Nel
7

Hasta donde yo sé, la dualtabla en Oracle es una tabla especial con solo una fila. Entonces, esto sería suficiente:

SELECT user
FROM dual
ypercubeᵀᴹ
fuente
Eso no es cierto seleccione un usuario de la doble debe darle todos los usuarios
Ben
También Wikipediaa bout dual en Oracle
ypercubeᵀᴹ
1
.. y acaba de probar en mi sistema, funciona como ypercube y toda la documentación relacionada menciona. @Ben
Sathyajith Bhat
1
@Ben dual no es una vista de catálogo, no mostrará "todos los usuarios". Usaría una vista como ALL_USERS para ese propósito.
makrom
7

👌 La respuesta es:

Debería utilizar consultas anidadas como:

SELECT *
FROM ANY_TABLE_X 
WHERE ANY_COLUMN_X = (SELECT MAX(ANY_COLUMN_X) FROM ANY_TABLE_X) 

=> En PL / SQL, "ROWNUM = 1" NO es igual a "TOP 1" de TSQL.

Por lo tanto, no puede usar una consulta como esta: "seleccione * de cualquier_tabla_x donde rownum = 1 pedido por cualquier_columna_x;" Debido a que Oracle obtiene la primera fila, luego aplica orden por cláusula.

Fuat
fuente
1
Agregue algunas aclaraciones a su respuesta
hgwhittle
Se debe evitar la sintaxis inusual sin una buena razón. En este caso, sería útil proporcionar un caso de prueba o un número de error. Recuerdo vagamente algunos problemas extraños con rownum = 1, pero no deberíamos permitir que los errores antiguos afecten más nuestro código.
Jon Heller
7
@hgwhittle, La razón por la que Fuat es correcta es porque a ROWNUM no le importa 'ordery by', simplemente toma el primer registro que puede encontrar y lo devuelve inmediatamente. En otras palabras, el calificador ROWNUM no tiene ningún respeto por el comando "Ordenar por". Desearía que ese no fuera el caso, pero Fuat es correcto, para usar la consulta anidada.
Eric Milliot-Martinez
5

No hay ninguna limit 1condición (eso es MySQL / PostgresSQL) en Oracle, debe especificar where rownum = 1.

Oh Chin Boon
fuente
5

"FirstRow" es una restricción y, por lo tanto, se encuentra en la wherecláusula, no en la selectcláusula. Y se llama rownum

select * from dual where rownum = 1;
gdoron está apoyando a Monica
fuente
1
Tenga en cuenta que esto no funcionará como se esperaba en combinación con ORDER BY, ya que el pedido solo ocurre después de la cláusula where. En otras palabras, para obtener la parte superior de una determinada consulta ordenada, rownum es completamente inútil.
Nyerguds
@Nyerguds, esto es solo una verdad a medias. Puede usar order by antes de Wherecon una consulta de View.
gdoron apoya a Monica el
4
¿Qué, entonces SELECT * FROM (SELECT * FROM ... WHERE ... ORDER BY ...) WHERE ROWNUM = 1? Bueno, eso puede funcionar, pero parece bastante tonto, tbh.
Nyerguds
2

Si cualquier fila sirve, intente:

select max(user)  
from table;

No cláusula donde.

Raihan
fuente
9
Seguramente solo te tomará unos segundos probarlo por ti mismo
Matt Donnan
1
select name, price
  from (
    select name, price, 
    row_number() over (order by price) r
      from items
  )
where r between 1 and 5; 
Andrés
fuente
1

select a.user from (select user from users order by user) a where rownum = 1

funcionará mejor, otra opción es:

select a.user 
from ( 
select user, 
row_number() over (order by user) user_rank, 
row_number() over (partition by dept order by user) user_dept_rank 
from users 
) a 
where a.user_rank = 1 or user_dept_rank = 2

en escenarios donde desea diferentes subconjuntos, pero supongo que también podría usar RANK()Pero, también me gusta, row_number() over(...)ya que no se requiere agrupación.

Tyler
fuente
0

Si desea recuperar solo la primera fila de un resultado ordenado con la menor cantidad de subconsultas, intente esto:

select *
  from ( select a.*
              , row_number() over ( order by sysdate_col desc ) as row_num
           from table_name a )
  where row_num = 1;
Jody Fedor
fuente
Donde sysdate_col sería el nombre de cualquier columna por la que desee ordenar y, por supuesto, table_name sería el nombre de la tabla de la que desea que provengan los datos ordenados.
Jody Fedor
-1

Más flexible de lo que select max()es:

select distinct first_row(column_x) over (order by column_y,column_z,...) from Table_A
Invitado
fuente