我感兴趣的是从数据库表中选择第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,你有我们可以引用的链接吗?


当前回答

我在这里有点晚了,但我已经在不需要窗口或使用的情况下做到了这一点

WHERE x IN (...)
SELECT TOP 1
--select the value needed from t1
[col2]
FROM
(
   SELECT TOP 2 --the Nth row, alter this to taste
   UE2.[col1],
   UE2.[col2],
   UE2.[date],
   UE2.[time],
   UE2.[UID]
   FROM
   [table1] AS UE2
   WHERE
   UE2.[col1] = ID --this is a subquery 
   AND
   UE2.[col2] IS NOT NULL
   ORDER BY
   UE2.[date] DESC, UE2.[time] DESC --sorting by date and time newest first
) AS t1
ORDER BY t1.[date] ASC, t1.[time] ASC --this reverses the order of the sort in t1

它似乎工作得相当快,尽管公平地说,我只有大约500行数据

这在MSSQL中有效

其他回答

SELECT * FROM emp a
WHERE  n = ( 
    SELECT COUNT( _rowid)
    FROM emp b
    WHERE a. _rowid >= b. _rowid
);

对于SQL server,下面的语句将返回给定表的第一行。

declare @rowNumber int = 1;
    select TOP(@rowNumber) * from [dbo].[someTable];
EXCEPT
    select TOP(@rowNumber - 1) * from [dbo].[someTable];

你可以这样循环遍历这些值:

WHILE @constVar > 0
BEGIN
    declare @rowNumber int = @consVar;
       select TOP(@rowNumber) * from [dbo].[someTable];
    EXCEPT
       select TOP(@rowNumber - 1) * from [dbo].[someTable];  

       SET @constVar = @constVar - 1;    
END;

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

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

在我看来,为了提高效率,您需要1)生成一个小于数据库记录数量的0到1之间的随机数,2)能够选择该位置的行。不幸的是,不同的数据库有不同的随机数生成器,以及在结果集中的某个位置选择一行的不同方法——通常您指定要跳过多少行和需要多少行,但不同的数据库有不同的做法。下面是在SQLite中为我工作的一些东西:

select * 
from Table 
limit abs(random()) % (select count(*) from Words), 1;

It does depend on being able to use a subquery in the limit clause (which in SQLite is LIMIT <recs to skip>,<recs to take>) Selecting the number of records in a table should be particularly efficient, being part of the database's meta data, but that depends on the database's implementation. Also, I don't know if the query will actually build the result set before retrieving the Nth record, but I would hope that it doesn't need to. Note that I'm not specifying an "order by" clause. It might be better to "order by" something like the primary key, which will have an index - getting the Nth record from an index might be faster if the database can't get the Nth record from the database itself without building the result set.

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