我感兴趣的是从数据库表中选择第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中有效

其他回答

对于SQL Server,一般的方法是通过行号:

SET ROWCOUNT @row --@row = the row number you wish to work on.

例如:

set rowcount 20   --sets row to 20th row

select meat, cheese from dbo.sandwich --select columns from table at 20th row

set rowcount 0   --sets rowcount back to all rows

这将返回第20行的信息。一定要在后面输入行数0。

PostgreSQL支持SQL标准定义的窗口函数,但它们很笨拙,所以大多数人使用(非标准)LIMIT / OFFSET:

SELECT
    *
FROM
    mytable
ORDER BY
    somefield
LIMIT 1 OFFSET 20;

这个例子选择了第21行。OFFSET 20告诉Postgres跳过前20条记录。如果您没有指定ORDER BY子句,则无法保证您将返回哪条记录,这很少有用。

SQL SERVER


从顶部选择第n条记录

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

从底部选择第n条记录

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID DESC) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

在标准的可选部分中有一些方法可以做到这一点,但许多数据库都支持自己的方法。

一个非常好的网站是http://troels.arvin.dk/db/rdbms/#select-limit。

基本上,PostgreSQL和MySQL支持非标准:

SELECT...
LIMIT y OFFSET x 

Oracle, DB2和MSSQL支持标准窗口函数:

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,
    columns
  FROM tablename
) AS foo
WHERE rownumber <= n

(我只是从上面链接的网站复制,因为我从不使用这些数据库)

更新:从PostgreSQL 8.4开始支持标准窗口函数,因此希望第二个示例也适用于PostgreSQL。

更新:SQLite在2018-09-15版本3.25.0中添加了窗口函数支持,因此这两种表单也可以在SQLite中工作。

WITH r AS (
  SELECT TOP 1000 * FROM emp
)
SELECT * FROM r
EXCEPT
SELECT TOP 999 FROM r

这将给出SQL Server中的第1000行。