我感兴趣的是从数据库表中选择第n行的一些(理想的)数据库不可知的方法。看看如何使用以下数据库的本机功能来实现这一点也很有趣:

SQL Server MySQL PostgreSQL SQLite 甲骨文

我目前正在SQL Server 2005中做以下事情,但我有兴趣看到其他更不可知论的方法:

WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000

以上SQL: Firoz Ansari的Weblog的功劳

更新:参见Troels Arvin关于SQL标准的回答。Troels,你有我们可以引用的链接吗?


当前回答

但说真的,所有这些不都是好的数据库设计的小把戏吗?有几次我需要这样的功能,它是为了一个简单的一次性查询,以快速生成报告。对于任何实际工作,使用这样的技巧都是在招惹麻烦。如果需要选择一个特定的行,那么只要有一个具有连续值的列就可以了。

其他回答

LIMIT n,1不能在MS SQL Server中工作。我认为它是唯一一个不支持这种语法的主流数据库。公平地说,它不是SQL标准的一部分,尽管它得到了如此广泛的支持,它应该是SQL标准的一部分。在一切除了SQL服务器限制工作得很好。对于SQL server,我还没有找到一个优雅的解决方案。

这就是我在DB2 SQL中如何做的,我相信RRN(相对记录号)由O/S存储在表中;

SELECT * FROM (                        
               SELECT RRN(FOO) AS RRN, FOO.*
               FROM FOO                         
               ORDER BY RRN(FOO)) BAR             
WHERE BAR.RRN = recordnumber

我怀疑这是一种非常低效的方法,但这是一种相当简单的方法,它在我尝试的一个小型数据集上有效。

select top 1 field
from table
where field in (select top 5 field from table order by field asc)
order by field desc

这将得到第5项,改变上面的第二个数字来得到不同的第n项

仅限SQL服务器(我认为),但应该适用于不支持ROW_NUMBER()的旧版本。

1个小变化,n-1而不是n。

select *
from thetable
limit n-1, 1

当我们在MSSQL 2000中工作时,我们做了所谓的“三重翻转”:

编辑

DECLARE @InnerPageSize int
DECLARE @OuterPageSize int
DECLARE @Count int

SELECT @Count = COUNT(<column>) FROM <TABLE>
SET @InnerPageSize = @PageNum * @PageSize
SET @OuterPageSize = @Count - ((@PageNum - 1) * @PageSize)

IF (@OuterPageSize < 0)
    SET @OuterPageSize = 0
ELSE IF (@OuterPageSize > @PageSize)
    SET @OuterPageSize = @PageSize

DECLARE @sql NVARCHAR(8000)

SET @sql = 'SELECT * FROM
(
    SELECT TOP ' + CAST(@OuterPageSize AS nvarchar(5)) + ' * FROM
    (
        SELECT TOP ' + CAST(@InnerPageSize AS nvarchar(5)) + ' * FROM <TABLE> ORDER BY <column> ASC
    ) AS t1 ORDER BY <column> DESC
) AS t2 ORDER BY <column> ASC'

PRINT @sql
EXECUTE sp_executesql @sql

它并不优雅,速度也不快,但它奏效了。