如何在SQL数据库表中选择第n行?
我对学习从数据库表中选择第n行的一些(理想的)数据库不可知方式感兴趣。看看如何使用以下数据库的本机功能来实现此目的也将很有趣:
- SQL服务器
- 的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
更新:有关SQL标准,请参见Troels Arvin的答案。 Troels,我们有没有我们可以引用的链接?
解决方案
回答
添加:
LIMIT n,1
这会将结果限制为从结果n开始的一个结果。
回答
LIMIT n,1在MS SQL Server中不起作用。我认为这只是唯一不支持该语法的主要数据库。公平地说,它不是SQL标准的一部分,尽管它得到了应有的广泛支持。除了SQL Server之外,LIMIT在所有情况下都非常有效。对于SQL Server,我一直无法找到一个优雅的解决方案。
回答
这是我最近为Oracle写的sproc的通用版本,它允许动态分页/排序HTH
-- p_LowerBound = first row # in the returned set; if second page of 10 rows, -- this would be 11 (-1 for unbounded/not set) -- p_UpperBound = last row # in the returned set; if second page of 10 rows, -- this would be 20 (-1 for unbounded/not set) OPEN o_Cursor FOR SELECT * FROM ( SELECT Column1, Column2 rownum AS rn FROM ( SELECT tbl.Column1, tbl.column2 FROM MyTable tbl WHERE tbl.Column1 = p_PKParam OR tbl.Column1 = -1 ORDER BY DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 1, Column1, 'X'),'X'), DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 1, Column1, 'X'),'X') DESC, DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate), DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate) DESC )) WHERE (rn >= p_lowerBound OR p_lowerBound = -1) AND (rn <= p_upperBound OR p_upperBound = -1);
回答
我不确定其余的任何内容,但是我知道SQLite和MySQL没有任何"默认"行顺序。至少在这两种方言中,以下片段从the_table中获取第15个条目,并按添加日期/时间排序:
SELECT * FROM the_table ORDER BY added DESC LIMIT 1,15
(当然,我们需要添加一个DATETIME字段,并将其设置为添加条目的日期/时间...)
回答
我怀疑这是非常低效的,但却是一种非常简单的方法,该方法适用于我尝试过的小型数据集。
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 Server(我认为),但应在不支持ROW_NUMBER()的旧版本上运行。
回答
PostgreSQL中的LIMIT / OFFSET语法为:
SELECT * FROM mytable ORDER BY somefield LIMIT 1 OFFSET 20;
本示例选择第21行。 " OFFSET 20"告诉Postgres跳过前20条记录。如果我们不指定ORDER BY
子句,则无法保证我们将获得哪条记录,这很少有用。
显然,SQL标准对疯狂的窗口函数之外的限制问题保持沉默,这就是为什么每个人都以不同的方式实现它的原因。
回答
当我们过去在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
它不是很优雅,也不是很快,但它确实有效。
回答
甲骨文:
select * from (select foo from bar order by foo) where ROWNUM = x
回答
但是,真的,所有这些难道不是真的只是为了良好的数据库设计而设计的绝招吗?几次我需要这样的功能,这是一个简单的一次性查询即可快速生成报告。对于任何实际工作,使用这样的技巧都会带来麻烦。如果需要选择特定的行,则只需具有一列具有顺序值的列即可。
回答
在Sybase SQL Anywhere中:
SELECT TOP 1 START AT n * from table ORDER BY whatever
不要忘记ORDER BY或者它毫无意义。
回答
在标准的可选部分中有执行此操作的方法,但是许多数据库都支持其自己的执行方法。
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。
回答
1个小变化:n-1而不是n。
select * from thetable limit n-1, 1
回答
与某些答案所声称的相反,SQL标准对此主题并没有保持沉默。
从SQL:2003开始,我们就可以使用"窗口函数"跳过行并限制结果集。
在SQL:2008中,使用
偏移跳过行
仅获取前n行`
就我个人而言,我不认为确实需要添加SQL:2008,因此,如果我是ISO,我将使它脱离本来就相当大的标准。
回答
令人难以置信的是,我们会发现执行此操作的SQL引擎...
WITH sentence AS (SELECT stuff, row = ROW_NUMBER() OVER (ORDER BY Id) FROM SentenceType ) SELECT sen.stuff FROM sentence sen WHERE sen.row = (ABS(CHECKSUM(NEWID())) % 100) + 1
回答
SELECT * FROM emp a WHERE n = (SELECT COUNT( _rowid) FROM emp b WHERE a. _rowid >= b. _rowid);
回答
对于SQL Server,按行号排序的通用方法如下:
SET ROWCOUNT @row-@ row =我们要处理的行号。
例如:
将rowcount设置为20-将行设置为第20行
从dbo.sandwich中选择肉类,奶酪-从第20行的表中选择列
set rowcount 0-将行计数设置回所有行
这将返回第20行的信息。请确保之后再放入行计数0。
我知道noobish,但是我是SQL noob,已经用过了,所以我该怎么说?
回答
SQL 2005及更高版本具有此内置功能。使用ROW_NUMBER()函数。对于具有<<上一页和下一页>>样式浏览的网页而言,它非常有用:
句法:
SELECT * FROM ( SELECT ROW_NUMBER () OVER (ORDER BY MyColumnToOrderBy) AS RowNum, * FROM Table_1 ) sub WHERE RowNum = 23
回答
T-SQL从表中选择第N个RecordNumber
select * from (select row_number() over (order by Rand() desc) as Rno,* from TableName) T where T.Rno = RecordNumber Where RecordNumber --> Record Number to Select TableName --> To be Replaced with your Table Name
例如要从表Employee中选择第5条记录,查询应为
select * from (select row_number() over (order by Rand() desc) as Rno,* from Employee) T where T.Rno = 5