SQL Server TOP的等价物

16

在 SQL Server 中,可以使用 TOP 命令返回查询结果中的前 n 行数据。例如,

SELECT TOP 100 * FROM users ORDER BY id
可以用来查询注册时间最早的前 100 名用户(这并不一定是最好的方法,只是一个示例)。

我的问题是 - 在其他数据库中,比如 Oracle、MySQL 和 PostgreSQL 等,有没有类似于 TOP 命令的关键字?如果没有类似的关键字,你能推荐哪些解决方法来达到相同的效果呢?


是否存在 ANSI SQL 中替代 MySQL LIMIT 关键字的方法? - Paul Tomblin
从技术上讲,是的。但前提是你要知道mysql的LIMIT关键字,而当时我并不知道。 - Justin Ethier
9个回答

21

选择前 100 行:

MySQLPostgreSQL

SELECT  *
FROM    Table
ORDER BY
        column
LIMIT 100

Oracle

SELECT  *
FROM    (
        SELECT  t.*
        FROM    table
        ORDER BY
                column
        )
WHERE   rownum <= 100

请注意,这里需要使用子查询。如果不添加子查询,ROWNUM会随机选择前10行,然后按column排序。

要选择100300之间的行:

MySQL

SELECT  *
FROM    TABLE
ORDER BY
        column
LIMIT   100, 200

PostgreSQL:


(PostgreSQL)
SELECT  *
FROM    Table
ORDER BY
        column
OFFSET 100 LIMIT 200

Oracle

SELECT  *
FROM    (
        SELECT  t.*, ROW_NUMBER() OVER (ORER BY column) AS rn
        FROM    table
        )
WHERE   rn >= 100
        AND rownum <= 200

请注意,在 Oracle 中,尝试使用 ROWNUM BETWEEN 100 AND 200(而不是外部查询中的 rn BETWEEN 100 AND 200)来简化它会返回空值。

RN BETWEEN 100 AND 200Oracle 中也可以工作,但效率较低。

请参阅我的博客文章以获取性能详细信息:


为什么这个没有标准化?@ocdecia发布的内容一点也不清楚,我认为MySQL和PostgreSQL的表示法是最好的。 - Pablote
@Pablote:因为Oracle比我年龄还大,而Sybase(SQL Server的基础)只比它年轻4岁。那个时候还没有任何标准。等到标准出现的时候,已经有太多的代码存在了,无法改变任何东西。 - Quassnoi
@Pablote:@ocdecio发布的是分析函数,而不是记录集限制。它们可以用于限制记录集,但这不是它们的主要目标。 - Quassnoi
@Quassnoi - 这是正确的,但它属于SQL3标准窗口函数,因此在我看来比使用每个供应商特定的语法更好。 - Otávio Décio
@ocdecio:在Oracle中,ROW_NUMBER始终比ROWNUM低效,并且有时比MS SQL中的TOP还不高效。 - Quassnoi
对于你的MySQL示例,你能指明哪个是限制数量,哪个是偏移量吗? - John Fouhy

6
对于Postgres和MySQL,关键字是LIMIT。
SELECT *
  FROM users
 ORDER BY id
 LIMIT 100;

3

这是标准的SQL语法(Oracle和SQL Server均可使用)。以下是返回前100行的示例:

        SELECT ID_CONTROL FROM (SELECT ROW_NUMBER() OVER (ORDER BY ID_CONTROL) 
        ROWNUMBER, ID_CONTROL FROM IWS_CONTROL WHERE 
        CURRENT_STATE = 15 AND CURRENT_STATUS=0) A WHERE ROWNUMBER <= 100)

2
在SQL Anywhere中,与SQL Server相同:
SELECT TOP 100 * FROM users ORDER BY id

如果您想的话,甚至可以从结果集中间开始:

SELECT TOP 100 START AT 50 * FROM users ORDER BY id

获取结果集中第50行到第150行。


1
LIMIT 100

就像

SELECT * FROM foo ORDER BY bar LIMIT 100

1

Oracle:

select * from (select * from foo ORDER BY bar) where rownum < 100

AskTom里有一个很好的解释如何让它工作。

在Ingres中,相同的查询将是:

select First 100 * from foo ORDER BY bar

Ingres的问题在StackOverflow上已经有答案了。


所以,查询应该是:select * from (select * from foo order by bar) where rownum <100以获取排序后的前100个... - Sean
哎呀,应该是<=100,因为rownum从1开始。 - Sean

1

在Oracle中,您可以使用RANK()和DENSE_RANK()。这里是一个链接到AskTom网站的页面,该页面解释了如何使用DENSE_RANK在Oracle中进行分页和Top-N查询。


1
在DB2中,您的查询应该像这样:
SELECT * FROM tblData FETCH FIRST 10 ROWS ONLY;

0

在Oracle中,您想要使用TOP-N查询。

例如:

select  *
  from  (SELECT  *
           FROM  foo
          where  foo_id=[number]
       order by  foo_id desc)
 where  rownum <= 3

这将会获取到前三个结果(因为我在子查询中按照降序排序)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接