最后 N 行

这是一个众所周知的问题,但我找到的最佳解决方案是这样的:

SELECT TOP N *
FROM MyTable
ORDER BY Id DESC

我有一张有很多行的桌子。使用该查询是不可能的,因为它需要很多时间。那么,如何在不使用 ORDERBY 的情况下选择最后 N 行呢?

剪辑

对不起,这个的重复问题

872195 次浏览

你也可以通过使用 ROW NUMBER BY PARTITION Feature 来实现:

我正在使用 Northwind 数据库的 Orders 表... 现在让我们检索由雇员5下达的最后5个订单:

SELECT ORDERID, CUSTOMERID, OrderDate
FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY OrderDate DESC) AS OrderedDate,*
FROM Orders
) as ordlist


WHERE ordlist.EmployeeID = 5
AND ordlist.OrderedDate <= 5

“ Id”被索引了吗? 如果没有,那是一件重要的事情(我怀疑它已经被索引了)。

还有,是否需要返回所有列?如果实际上只需要 ID 列上的索引能够完全满足的较小的列子集,那么速度可能会得到很大的提高——例如,如果 ID 列上有一个 NONCLUSTERED 索引,索引中没有包含其他字段,那么它将不得不对聚集索引进行查找,以实际获得要返回的其余列,这可能会弥补查询的大量成本。如果它是一个 CLUSTERED 索引,或者一个非 CLUSTERED 索引,其中包含查询中要返回的所有其他字段,那么应该没有问题。

我测试了 JonVD 的代码,但发现它非常慢,6s。

这个代码需要0。

SELECT TOP(5) ORDERID, CUSTOMERID, OrderDate
FROM Orders where EmployeeID=5
Order By OrderDate DESC

不使用 order by显示最后3行:

select * from Lms_Books_Details where Book_Code not in
(select top((select COUNT(*) from Lms_Books_Details ) -3 ) book_code from Lms_Books_Details)

您可以通过以下查询让 SQL server 选择最后 N 行:

select * from tbl_name order by id desc limit N;

这里有一些东西,你可以尝试没有一个 order by,但我认为它要求每一行是唯一的。N是所需的行数,L是表中的行数。

select * from tbl_name except select top L-N * from tbl_name

如前所述,返回的行是未定义的。

编辑: 这实际上是狗慢。真的没有价值。

如果要从表中选择最后的行数。

语法就像

 select * from table_name except select top
(numbers of rows - how many rows you want)* from table_name

这些陈述有不同的作用方式,谢谢大家。

 select * from Products except select top (77-10) * from Products

这样你可以得到最后10行,但顺序将显示下降的方式

select top 10 * from products
order by productId desc

 select * from products
where productid in (select top 10 productID from products)
order by productID desc

 select * from products where productID not in
(select top((select COUNT(*) from products ) -10 )productID from products)
select * from (select top 6 * from vwTable order by Hours desc) T order by Hours

尝试使用 EXCEPT语法。
就像这样:

   SELECT *
FROM   clientDetails
EXCEPT
(SELECT TOP (numbers of rows - how many rows you want) *
FROM   clientDetails)

首先你得到的记录数量最多的是

 Declare @TableRowsCount Int
select @TableRowsCount= COUNT(*) from <Your_Table>

然后:

在 SQLServer2012中

SELECT *
FROM  <Your_Table> As L
ORDER BY L.<your Field>
OFFSET <@TableRowsCount-@N> ROWS
FETCH NEXT @N ROWS ONLY;

在 SQLServer2008中

SELECT *
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS sequencenumber, *
FROM  <Your_Table>
Order By <your Field>
) AS TempTable
WHERE sequencenumber > @TableRowsCount-@N

此查询以正确的顺序返回最后 N 行,但性能较差

select *
from (
select top N *
from TableName t
order by t.[Id] desc
) as temp
order by temp.[Id]

这个问题可能不太合适,但是..。

OffSET 子句

OFFSET number子句使您能够跳过 号码行,然后返回其后的行。

文档链接是到 Postgres 的,我不知道这是否适用于 Sybase/MS SQL Server。

DECLARE @MYVAR  NVARCHAR(100)
DECLARE @step  int
SET @step = 0;




DECLARE MYTESTCURSOR CURSOR
DYNAMIC
FOR
SELECT col FROM [dbo].[table]
OPEN MYTESTCURSOR
FETCH LAST FROM MYTESTCURSOR INTO @MYVAR
print @MYVAR;




WHILE @step < 10
BEGIN
FETCH PRIOR FROM MYTESTCURSOR INTO @MYVAR
print @MYVAR;
SET @step = @step + 1;
END
CLOSE MYTESTCURSOR
DEALLOCATE MYTESTCURSOR

以一种非常通用的方式,并且在这里支持 SQL 服务器是

SELECT TOP(N) *
FROM tbl_name
ORDER BY tbl_id DESC

就性能而言,它还不错(对于服务器机器上的10,000条记录而言,不到一秒钟)

我用于查询非常大的表 (1亿或10亿行)中的 最近的行的一种技术是将查询限制为只“读取”最近的 RECENT ROWS 的“ N”百分比。这是真实世界的应用程序,例如,我这样做是为了非历史性的最近天气数据,或最近的新闻提要搜索或最近的 GPS 位置数据点数据。

这是一个 巨大的绩效改善,如果您确信您的行位于表中最近的 TOP 5% 中,例如。这样,即使表上有索引,它也会进一步将可能性限制为表中有100 + 000万或10 + 000万行的行的5% 。当旧数据需要 物理磁盘读取而不仅仅是 内存中的逻辑读取时,情况尤其如此。

这比 SELECT TOP | PERCENT | LIMIT 更有效,因为它不选择行,而只是限制要搜索的数据部分。

DECLARE @RowIdTableA BIGINT
DECLARE @RowIdTableB BIGINT
DECLARE @TopPercent FLOAT


-- Given that there is an Sequential Identity Column
-- Limit query to only rows in the most recent TOP 5% of rows
SET @TopPercent = .05
SELECT @RowIdTableA = (MAX(TableAId) - (MAX(TableAId) * @TopPercent)) FROM TableA
SELECT @RowIdTableB = (MAX(TableBId) - (MAX(TableBId) * @TopPercent)) FROM TableB


SELECT *
FROM TableA a
INNER JOIN TableB b ON a.KeyId = b.KeyId
WHERE a.Id > @RowIdTableA AND b.Id > @RowIdTableB AND
a.SomeOtherCriteria = 'Whatever'

在查询的末尾使用 desc 和 orderby 来获取最后的值。

MS 不支持 t-sql 中的极限,大多数情况下我只是得到最大值(ID)然后再减去。

select * from ORDERS where ID >(select MAX(ID)-10 from ORDERS)

如果 ID 不是连续的,这将返回少于10条记录。

我在使用 SQL 服务器时遇到了这个问题 我解决这个问题的方法是,对结果按顺序下降,然后给出结果的行号,在我过滤了结果之后,再把它们反过来。

  SELECT *
FROM (
SELECT *
,[rn] = ROW_NUMBER() OVER (ORDER BY [column] DESC)
FROM [table]
) A
WHERE A.[rn] < 3
ORDER BY [column] ASC

简单复制粘贴答案

为了按升序得到结果

SELECT n.*
FROM
(
SELECT *
FROM MyTable
ORDER BY id DESC
LIMIT N
) n
ORDER BY n.id ASC