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


当前回答

SELECT
    top 1 *
FROM
    table_name
WHERE
    column_name IN (
        SELECT
            top N column_name
        FROM
            TABLE
        ORDER BY
            column_name
    )
ORDER BY
    column_name DESC

我写这个查询是为了求第n行。 使用此查询的示例如下

SELECT
    top 1 *
FROM
    Employee
WHERE
    emp_id IN (
        SELECT
            top 7 emp_id
        FROM
            Employee
        ORDER BY
            emp_id
    )
ORDER BY
    emp_id DESC

其他回答

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

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

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

select * from 
(select * from ordered order by order_id limit 100) x order by 
x.order_id desc limit 1;

首先按升序选择前100行,然后按降序选择最后一行并限制为1行。然而,这是一个非常昂贵的语句,因为它访问了两次数据。

我不确定其他的,但我知道SQLite和MySQL没有任何“默认”行排序。至少在这两种方言中,下面的代码片段从the_table中抓取了第15个条目,按添加的日期/时间排序:

SELECT * 
FROM the_table 
ORDER BY added DESC 
LIMIT 1,15

(当然,您需要添加一个DATETIME字段,并将其设置为条目添加的日期/时间…)

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

这里有一个快速解决你困惑的方法。

SELECT * FROM table ORDER BY `id` DESC LIMIT N, 1

这里你可以通过填充N=0得到最后一行,通过填充N=1得到倒数第二行,通过填充N=3得到倒数第四行,等等。

这是面试中很常见的问题,也是一个很简单的回答。

如果你想要数量,ID或一些数字排序顺序,你可以在MySQL中使用CAST函数。

SELECT DISTINCT (`amount`) 
FROM cart 
ORDER BY CAST( `amount` AS SIGNED ) DESC 
LIMIT 4 , 1

在这里,通过填写N = 4,您将能够从CART表中获得第五次最高金额记录。您可以匹配字段和表名并提出解决方案。