我如何在Oracle中排名第一?


251

我该怎么做?

select top 1 Fname from MyTbl

Oracle 11g中




3
您能告诉我们您要“排名第一”的顺序吗?
Andrew Wolfe 2014年

1
首先,永远不要依赖数据库引擎来做到这一点。如果您想了解类似的信息,请放入音序器。当您这样做时,可以确保将按照插入顺序对它们进行编号。
FlyingGuy 2015年

1
关于该主题的非常有用的
Ilia Maskov

Answers:


257

如果只想选择第一行,则可以:

select fname from MyTbl where rownum = 1

您还可以使用分析函数对前x进行排序和取值:

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

54
如果您只想要1行,而不管哪一行,那么这很好。如果您想要特定的行(例如最近的记录),则需要在子选择中进行排序,例如Vash的答案。Oracle在排序之前分配行数。
Scott Bailey 2010年

4
@斯科特 那是正确的。和Patrick在一起,我认为语法不正确。确实应该保留(dense_rank()last ...)
mcpeterson 2010年

2
第一个示例和第二个示例之间的区别在于,第一个示例选择A行(任何行,无顺序)。第二个示例获取第一行的值,而无需执行订单内部查询(如下例所示)。
JulesLt

3
从MYTBL选择MAX(FNAME)以上(由some_factor等级()顺序排列):在不正确的语法
斯特凡格柏

1
@jclozano“不是oracle的一个非常知名的功能”-敬请谅解。这很重要,因为“不为人所知的功能”往往意味着晦涩难懂,因此可能暗示我们应该避免使用。这并不是很模糊,不应该避免使用它。
Sepster

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

8
此答案正确获取了TOP行(在限制ROWNUM之前对结果进行排序)。
JulesLt

这个答案不是确切的翻译-原始查询没有ORDER BY,也没有返回表中的所有列。
OMG小马

我已改正(见下文)。时间到时将切换投票。
JulesLt

7
@OMGPonies是的。但可能是大多数人通过谷歌搜索他们的问题而真正想要的东西
NimChimpsky

4
这肯定是该主题中的成功答案。我可能会添加一条便条,top X可以将其更改为WHERE ROWNUM <= X
SomethingSomething,

31

使用Oracle 12c(2013年6月),您可以像以下方式使用它。

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

6
有趣的命令,我在这里使用12c,OFFSET 0 ROWS显然不是必需的,您可以使用FETCH NEXT 1 ROWS ONLY甚至FETCH FIRST ROW ONLY,按的顺序很重要,否则将等同于仅使用a WHERE rownum = 1。我什至在OUTER APPLY指令中进行了尝试,它的工作方式类似于Ms-SQL的TOP函数。
拉斐尔·梅林

您说对了@RafaelMerlin。在您发表文章后,我意识到没有必要使用OFFSET 0 ROWS。获取顶级X和Y.顶部之间的数据时,这将是有益的
MSK


到目前为止一切顺利,还有一个重要的遗漏点是TIES。有关版本和版本之间发生联系的情况,请参考此内容12c +12c -
BarbarosÖzhan19年

10

你可以使用ROW_NUMBER()一个ORDER BY子查询子句和更换使用此列TOP N。这可以逐步解释。

请参阅下表,其中有两列NAMEDT_CREATED

在此处输入图片说明

如果您只需要输入前两个日期,而不必考虑NAME,则可以使用以下查询。逻辑已写入查询中

-- 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;

结果

在此处输入图片说明

在某些情况下,我们需要选择TOP N与每个结果相对应的结果NAME。在这种情况下,我们可以使用PARTITION BYORDER BY子查询子句。请参考以下查询。

-- 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;

结果

在此处输入图片说明


1
与主题答案相比,使用ROW_NUMBER()...是更正确的解决方案。此解决方案(以及max(field)变体)的一个问题是,您无法执行“选择...(选择ROW_NUMBER()...)进行更新;”之类的事情。
Alexo Po。

这在PL / SQL中有时非常重要(对不起,在5分钟内未能编辑先前的注释)。
Alexo Po。

在这种情况下,我们可以在外部使用CTE。对?@Alexo Po。
Sarath Avanavu 2015年

我想我听不懂你的话。当Oracle“轻松”保留ROWID时,可以使用for update子句。因此,分组(以及由于分析子句的使用而分组)隐藏了真实的ROWID,并且行无法锁定。其次,CTE(with (select ... ) as 子句)对此问题没有任何改变,CTE只是旨在阅读和支持查询。对?@Sarath Avanavu
Alexo Po。

注意我自己。ROWID的问题实际上是由于RNO <3条件而发生的,在这种情况下,RNO的值未与ROWID连接,因此这就是Oracle无法锁定行的原因。
Alexo Po。

9

你可以做类似的事情

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

您也可以使用解析函数RANK和/或DENSE_RANK,但是ROWNUM可能是最简单的。


1
你能帮忙举例说明一下等级
吗?

9
select * from (
    select FName from MyTbl
)
where rownum <= 1;

5

用:

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

如果使用Oracle9i +,则可以使用ROW_NUMBER()之类的解析函数,但它们的性能不如ROWNUM


1
好的答案,但有一个小的错字。您在哪里说Oracle9i +不应该是8i?download-west.oracle.com/docs/cd/A87860_01/doc/server.817/…–
伊恩·卡彭特

@carpenteri:的确,分析在8i中可用-记不清细节,但是直到9i才真正向公众提供分​​析。
OMG Ponies,2010年

小注释-Vash在下面的答案包括内部查询上的ORDER BY,这对于要使用fname的TOP值而不是“ first”(可以是任何东西,很可能是插入的第一行)至关重要。值得编辑吗?
JulesLt

@JulesLt:OP提供的查询不包含ORDER BY,因此这是答案表示形式,是对Oracle语法的准确翻译。
OMG小马

我对SQL SERVER TOP语法的误解(错误地认为它类似于RANK中的FIRST,而不是ROWNUM)。投票了。
JulesLt

3

要从表中选择第一行并从表中选择一行是两个不同的任务,并且需要不同的查询。有许多可能的方法可以这样做。其中四个是:

第一

select  max(Fname) from MyTbl;

第二

select  min(Fname) from MyTbl;

第三

select  Fname from MyTbl  where rownum = 1;

第四

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

3

我遇到了同样的问题,可以使用以下解决方案解决此问题:

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

您可以先排序结果,然后再将第一个值放在首位。

祝好运

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.