我感兴趣的是从数据库表中选择第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,你有我们可以引用的链接吗?
在我看来,为了提高效率,您需要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.
如果你想查看本机功能:
MySQL, PostgreSQL, SQLite和Oracle(基本上SQL Server似乎没有这个函数),你实际上可以使用NTH_VALUE窗口函数。
Oracle来源:Oracle函数:NTH_VALUE
实际上,我已经在我们的Oracle DB中对此进行了一些实验,以比较第一行(排序后)和第二行(同样是排序后)。
代码看起来像这样(如果你不想去链接):
SELECT DISTINCT dept_id
, NTH_VALUE(salary,2) OVER (PARTITION BY dept_id ORDER BY salary DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
AS "SECOND HIGHEST"
, NTH_VALUE(salary,3) OVER (PARTITION BY dept_id ORDER BY salary DESC
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
AS "THIRD HIGHEST"
FROM employees
WHERE dept_id in (10,20)
ORDER
BY dept_id;
我发现它很有趣,我希望他们能让我用它。
这里有一个快速解决你困惑的方法。
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表中获得第五次最高金额记录。您可以匹配字段和表名并提出解决方案。