如何从Oracle SQL中仅选择1行?


110

我想使用oracle语法从table中仅选择1行DUAL。例如,我要执行以下查询:

SELECT user 
  FROM DUAL

...它会有40条记录 但是我只需要一个记录。...而且,我希望没有WHERE子句就可以实现。

我在table_name字段中需要一些东西,例如:

SELECT FirstRow(user) 
  FROM DUAL

1
什么版本的Oracle?使用ROWNUM或ROW_NUMBER(9i +)意味着需要WHERE子句
OMG Ponies 2012年

1
你有桌子dual吗?
ypercubeᵀᴹ

1
@ypercube dual是oracle中的系统表

4
@Ben,您真的不应该创建一个名为的表DUAL。有点像#define TRUE 0在C语言中-当然,它可能对您有用,但是将来的开发人员会讨厌您。
杰弗里·肯普

3
您实际上尝试过跑步select user from dual吗?如果没有,请尝试一下,然后看看会得到什么。在标准的oracle系统上,您将获得执行命令的用户。
Shannon遣散费

Answers:


169

您使用ROWNUM。

即。

SELECT user FROM Dual WHERE ROWNUM = 1

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


据我所知,@ ypercube确实可以。(至少它为我安装的Oracle10g的。)

@bdares:可以,是的。但不是您的答案,请使用order by
ypercubeᵀᴹ

1
是。ROWNUM是一个特殊列,被添加到结果集中以枚举结果。您也可以使用它来选择多个雇员,例如,如果您想找到10个收入最高的雇员,您可能会说“从雇员中选择ROWNUM <= 10的雇员按薪水降序排列”
mindvirus 2012年

10
@mkdess:否,ORDER BY在之后应用WHERE
ypercubeᵀᴹ

15
你需要:SELECT * FROM (SELECT user FROM Employees ORDER BY SALARY DESC) WHERE ROWNUM <= 10
ypercubeᵀᴹ

49

我发现此“解决方案”隐藏在其中一个评论中。由于我已经查找了一段时间,因此我想对其进行一些突出显示(尚无法评论或做类似的事情...),所以这是我所使用的:

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

假设始终通过SYSDATE插入[日期],这将从表格的最新条目中打印所需的[列]条目。


我发现如果您按排序ROWID,它也将起作用,只要您从不删除任何记录并且始终关心最后插入/修改的记录即可。
vapcguy '16

@vapcguy:即使您从未从表中删除行,也不要期望ROWID会被排序!即使它现在对您有用,也永远不能保证它在将来的版本中起作用。
D. Mika's

@ D.Mika实际上,如果现在可以使用,并且您从不添加/删除/更新/删除记录,则应该永远不会有任何问题。仅当您实际更改记录时,才能更改记录。有一种误解,认为ROWIDOracle 会以某种方式对其进行随机修改。不是。它基于实际修改的行,即删除一行,然后插入一行。插入的将得到旧的ROWID。诸如静态表之类的东西永远都不会得到更新,例如在美国,这就是一个很好的例子。如果更改静态表,则在可能的情况下可能会有其他影响。
vapcguy

@vapcguy:好吧,那几乎是正确的。但是还有其他操作会更改ROWID。如果出于某种原因导出/导入表怎么办?还有其他操作,但是其中一些操作需要启用行运动。我只想说,依赖将来可能会更改的实现细节不是一个好主意。
D. Mika

@ D.Mika我确定是否有任何ROWID可以更改的操作,如果我可能描述了这样的静态表,那么好的DBA会查找它们并尽力避免它们仅应在该应用程序上运行。可以使用SELECT语句来完成表导出。导入将发生一次,然后再也不会发生。我明白你的意思,绝对需要谨慎,但问题并非不可避免。
vapcguy

35

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;

^^我只是想证明无论行数是多少,都可以使用一行或多行(复数)。)


1
select * from some_table仅获取前1行;它在我的swl devloper或sql中均不起作用,因此提取时出错。
nikhil sugandh

您正在使用oracle 12c吗?
mancini0

我真的不知道,但是当我打开它时,它显示如下:SQL * PLus版本10.1.0.4.2是否不是12 c
nikhil sugandh

正确-您正在使用可能使用的版本10.1.xxx,可以选择* FROM V $ VERSION
mancini0 '18

10

我们有3个选择来获取Oracle DB表的第一行。

1) select * from table_name where rownum= 1是最好的方法

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

感谢您的回答:在第3点下,“ nowrum = 1”可能应该更改为“ rownum = 1”。
安德烈·内尔

7

据我所知,dualOracle中的表是一个只有一行的特殊表。因此,这足够了:

SELECT user
FROM dual

并非如此,从双重选择用户中应该会给您所有用户
2012年


1
..并在我的系统上进行了尝试,可以作为ypercube和所有相关文档提及。@Ben
Sathyajith Bhat

1
@Ben dual不是目录视图,它不会显示“所有用户”。为此,您将使用诸如ALL_USERS之类的视图。
makrom

7

👌答案是:

您应将嵌套查询用作:

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

=>在PL / SQL中,“ ROWNUM = 1”不等于TSQL的“ TOP 1”。

因此,您不能使用这样的查询:“从any_table_x中选择*,其中rownum = 1由any_column_x排序;” 因为oracle获取第一行然后应用order by子句。


1
请为您的答案添加一些说明
hgwhittle 2014年

没有正当理由,应避免使用异常的语法。在这种情况下,提供测试用例或错误号将很有帮助。我隐约记得有关的一些怪异问题rownum = 1,但我们不应该再让旧错误影响我们的代码。
乔恩·海勒2014年

7
@hgwhittle,Fuat之所以正确是因为ROWNUM不在乎“排序依据”,它只是抓住它可以找到的第一个记录并立即返回它。因此,换句话说,ROWNUM限定词对“ Order By”命令没有任何尊重。我希望不是这种情况,但是Fuat是正确的,可以使用嵌套查询。
Eric Milliot-Martinez's

5

limit 1Oracle中没有条件(即MySQL / PostgresSQL),您需要指定where rownum = 1


5

“ FirstRow”是一个限制,因此它位于where子句中而不是select子句中。它叫做rownum

select * from dual where rownum = 1;

1
请注意,与结合使用时ORDER BY,这将无法按预期方式工作,因为排序仅 where子句之后进行。换句话说,要获得某个排序查询的顶部,rownum完全没有用。
Nyerguds

@Nyerguds,这只是一半正确。您可以在WhereView查询之前使用order by 。
gdoron在2013年

4
是什么,让SELECT * FROM (SELECT * FROM ... WHERE ... ORDER BY ...) WHERE ROWNUM = 1?好吧,这也许行得通,但是看起来很愚蠢,TBH。
Nyerguds

2

如果有行,请尝试:

select max(user)  
from table;

没有where子句。


9
当然,它只会需要几秒钟让你尝试为你自己
马特·唐南

1
select name, price
  from (
    select name, price, 
    row_number() over (order by price) r
      from items
  )
where r between 1 and 5; 

1

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

将执行最佳,另一个选择是:

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

在需要不同子集的情况下,但我想您也可以使用RANK()但是,我也很喜欢,row_number() over(...)因为不需要分组。


0

如果您只想返回排序结果的第一行,且子查询最少,请尝试以下操作:

select *
  from ( select a.*
              , row_number() over ( order by sysdate_col desc ) as row_num
           from table_name a )
  where row_num = 1;

其中sysdate_col是要排序的任何列的名称,当然,table_name是要从中获得排序数据的表的名称。
乔迪·费多

-1

比以下更灵活select max()

select distinct first_row(column_x) over (order by column_y,column_z,...) from Table_A
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.