How to select only 1 row from oracle sql?
Asked Answered
C

14

171

I want to use oracle syntax to select only 1 row from table DUAL. For example, I want to execute this query:

SELECT user 
  FROM DUAL

...and it'd have, like, 40 records. But I need only one record. ...AND, I want to make it happen without a WHERE clause.

I need something in the table_name field such as:

SELECT FirstRow(user) 
  FROM DUAL
Crackbrain answered 19/1, 2012 at 0:22 Comment(10)
What version of Oracle? Using ROWNUM or ROW_NUMBER (9i+) would mean needing a WHERE clauseCastano
Did you name a table dual ?Blatman
@ypercube dual is the system table in oracleWadlinger
@bdares: Exactly. So, can someone create another one with same name?Blatman
@ypercube no. the dual table does have a user column, though. The "no where clause" constraint seems... contrived? Why the heck not?Wadlinger
ROWNUM(9i+) , do you have an answer?Crackbrain
@Ben, you really shouldn't create a table called DUAL. It's a bit like #define TRUE 0 in C - sure, it might work for you, but future developers will hate you.Samualsamuel
Have you actually tried to run select user from dual? If not, please try that, and see what you get. On a standard oracle system, you'll get back the user you are executing the command with.Plumcot
possible duplicate of How to do top 1 in Oracle?Meyers
Old question but I'm voting to close as unclear. DUAL only has one row. If you have two rows in it or another table called dual or you meant a different table then that changes the question.Karilynn
C
220

You use ROWNUM.

ie.

SELECT user FROM Dual WHERE ROWNUM = 1

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

Cort answered 19/1, 2012 at 0:25 Comment(6)
@ypercube far as I can tell, it does. (At least it works for my installation of oracle10g.)Wadlinger
@bdares: it will work, yes. But not your answer, with the order by.Blatman
Yes. ROWNUM is a special column that gets added to the result set enumerating the results. You can use it to select multiple as well, for example, if you wanted to find the 10 highest payed employees, you might say "SELECT user FROM Employees WHERE ROWNUM <= 10 ORDER BY SALARY DESCENDING"Cort
@mkdess: No, ORDER BY is applied after the WHERE.Blatman
You'd need: SELECT * FROM (SELECT user FROM Employees ORDER BY SALARY DESC) WHERE ROWNUM <= 10Blatman
ROWNUM doesn't work, ROWNUM() works , and i don't know the version i need to ask at work anyone know the answer ? can't i use some special proc to avoid the where?Crackbrain
J
92

This syntax is available in 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;

^^I just wanted to demonstrate that either row or rows (plural) can be used regardless of the plurality of the desired number of rows.)

Jamijamie answered 10/4, 2017 at 21:25 Comment(4)
select * from some_table fetch first 1 row only; its not working in my swl devloper nor in sql plus so error at fetch.Southernmost
Are you using oracle 12c?Jamijamie
i dont really know but when i open it it shows like this: SQL * PLus Release 10.1.0.4.2 is it not 12 cSouthernmost
correct - you are using likely using version 10.1.xxx , you can SELECT * FROM V$VERSIONJamijamie
I
62

I found this "solution" hidden in one of the comments. Since I was looking it up for a while, I'd like to highlight it a bit (can't yet comment or do such stuff...), so this is what I used:

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

This will print me the desired [Column] entry from the newest entry in the table, assuming that [Date] is always inserted via SYSDATE.

Ingrained answered 30/7, 2014 at 8:42 Comment(5)
I found it will also work if you order by ROWID, as long as you never delete any records and always care about the last inserted/modified one.Ullman
@vapcguy: Don't expect ROWID to be ordered, even if you never delete a row from the table! Even if it works for you now, it is never guaranteed to work in future versions.Doan
@D.Mika Actually if it works now, and you never add/remove/update/delete records, there should never be any issues. The records can only be changed if you actually change them. There is this misconception that somehow ROWID is randomly modified by Oracle. It isn't. It is based on actually modifying the rows, i.e. you delete one, then insert one. The inserted one will get the old one's ROWID. There are such things as static tables that never get updated-like states in the U.S. is a good example-where if it changed, it would probably have other repercussions, anyway, when this is fine.Ullman
@vapcguy: Well, thats almost right. But there are other operations that will change the ROWID. What if you export / import the table for some reason? There are others operation, but some of them need ENABLE ROW MOVEMENT. I just want to say it's no good idea to rely on an implementation detail that may change in the future.Doan
@D.Mika I'm sure if there are any operations where the ROWID could be changed, a good DBA would look them up and do what they could to avoid them if there was the possibility they were affecting such a static table as I described that only the application should be operating on. A table export can be done with a SELECT statement, instead. The import would happen once and then never again. I get your point, care is definitely needed, but the issues are far from unavoidable.Ullman
E
16

we have 3 choices to get the first row in Oracle DB table.

1) select * from table_name where rownum= 1 is the best way

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
Excrescency answered 26/12, 2017 at 10:17 Comment(2)
Thanks for the answers: under point 3) "nowrum= 1" should probably be changed to "rownum = 1".Neolith
First option works!Labellum
N
10

👌 The answer is:

You should use nested query as:

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

=> In PL/SQL "ROWNUM = 1" is NOT equal to "TOP 1" of TSQL.

So you can't use a query like this: "select * from any_table_x where rownum=1 order by any_column_x;" Because oracle gets first row then applies order by clause.

Nonexistence answered 9/1, 2014 at 14:34 Comment(3)
Please add some clarification to your answerAniseed
Unusual syntax should be avoided without a good reason. In this case, it would be helpful to provide either a test case or a bug number. I vaguely recall some weird issues with rownum = 1, but we shouldn't let old bugs affect our code anymore.Siegbahn
@hgwhittle, The reason why Fuat is correct is because ROWNUM doesn't care about 'ordery by', it just grabs the first record it can find and immediately returns it. So in other words, the ROWNUM qualifier doesn't have any respect for "Order By" command. I wish that wasn't the case but Fuat is correct, to use the nested query.Melanism
W
6

As far as I know, the dual table in Oracle is a special table with just one row. So, this would suffice:

SELECT user
FROM dual
Wyndham answered 19/1, 2012 at 0:36 Comment(4)
that's not true select user from dual should give you all the usersCrackbrain
So does Wikipediaa bout dual in OracleBlatman
.. and just tried out on my system, works as ypercube & all related documentation mentions. @CrackbrainTry
@Crackbrain dual is not a catalog view, it won't show "all the users". You would use a view like ALL_USERS for that purpose.Visage
P
5

There is no limit 1 condition (thats MySQL / PostgresSQL) in Oracle, you need to specify where rownum = 1.

Plumbum answered 19/1, 2012 at 0:27 Comment(0)
H
4

"FirstRow" Is a restriction and therefor it's place in the where clause not in the select clause. And it's called rownum

select * from dual where rownum = 1;
Haematogenous answered 19/1, 2012 at 0:29 Comment(3)
Note that this will not work as expected in combination with ORDER BY, since ordering only happens after the where clause. In other words, to get the top of a certain sorted query, rownum is utterly useless.Fastback
@Nyerguds, this is only half true. You can use order by before the Where with a View query.Haematogenous
What, so SELECT * FROM (SELECT * FROM ... WHERE ... ORDER BY ...) WHERE ROWNUM = 1? Well, that may work, but it looks pretty dumb, tbh.Fastback
S
4

If you want to get back only the first row of a sorted result with the least subqueries, try this:

select *
  from ( select a.*
              , row_number() over ( order by sysdate_col desc ) as row_num
           from table_name a )
  where row_num = 1;
Swayder answered 24/6, 2020 at 14:19 Comment(1)
Where sysdate_col would be the name of any column you want to sort by and of course, table_name would be the name of the table you want the sorted data to come from.Swayder
D
2

If any row would do, try:

select max(user)  
from table;

No where clause.

Dissever answered 19/1, 2012 at 0:28 Comment(1)
Surely it will only take seconds for you to try that out for yourselfGalliett
S
1
select name, price
  from (
    select name, price, 
    row_number() over (order by price) r
      from items
  )
where r between 1 and 5; 
Stead answered 24/8, 2015 at 19:40 Comment(0)
M
1

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

will perform the best, another option is:

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

in scenarios where you want different subsets, but I guess you could also use RANK() But, I also like row_number() over(...) since no grouping is required.

Merl answered 22/8, 2019 at 18:19 Comment(0)
P
0

More flexible than select max() is:

select distinct first_row(column_x) over (order by column_y,column_z,...) from Table_A
Patrizius answered 2/4, 2014 at 13:43 Comment(0)
P
0

In oracle 11g, The below example can be helpful....

 SELECT *
 FROM
 (
    SELECT *
        
    FROM RF_ACTN_STATUS STS 
    WHERE 
        STS.RF_ACTN_TYPE_ID=27 AND 
        STS.ACTION_SORT>2 AND 
        NVL(STS.IS_RESEND,'N')='N' AND 
        NVL(STS.IS_CANCELLED_STATIUS,'N')='N'            
    ORDER BY STS.ACTION_SORT ASC
) X
WHERE ROWNUM = 1
        ;
Platitudinous answered 14/2, 2023 at 11:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.