SQL Server SELECT最后N行

Die*_*ego 124 sql sql-server performance sql-server-2008

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

SELECT TOP N *
FROM MyTable
ORDER BY Id DESC
Run Code Online (Sandbox Code Playgroud)

我有一张有很多行的桌子.使用该查询不是一种可能性,因为它需要花费大量时间.那么如何在不使用ORDER BY的情况下选择最后N行呢?

编辑

抱歉这个重复的问题

Nir*_*hah 88

您可以使用此SQL使SQL服务器选择最后N行:

select * from tbl_name order by id desc limit N;
Run Code Online (Sandbox Code Playgroud)

  • 这在SQL Server中不起作用.看起来像MySQL,PostgreSQL和SQLite功能. (57认同)
  • @ gena2x这个问题被标记为SQL Server.该标记指的是Microsoft SQL Server. (5认同)
  • 所有枚举产品都是绝对的SQL服务器.如果你想谈谈MS SQL服务器,为什么不这样命名呢? (3认同)
  • 我很困惑,问题是如何创建一个选择查询"不使用ORDER BY",你的答案中的选择查询有"order by".这是某种"没有"顺序"的"顺序"吗? (3认同)
  • 版本兼容性怎么样? (2认同)

ABI*_*ABI 45

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

这段代码用了0秒.

SELECT TOP(5) ORDERID, CUSTOMERID, OrderDate    
FROM Orders where EmployeeID=5    
Order By OrderDate DESC
Run Code Online (Sandbox Code Playgroud)

  • 多少行?当你有很多行可以是REALY慢 (4认同)
  • 这将使行倒置。然后,您必须由他们重新订购才能恢复原始订单。 (2认同)

Jon*_*nVD 35

您也可以使用ROW NUMBER BY PARTITION功能来完成此操作.一个很好的例子,可以发现在这里:

我正在使用Northwind数据库的Orders表...现在让我们检索Employee 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
Run Code Online (Sandbox Code Playgroud)


小智 15

如果要从表中选择最后一行数.

语法就像

 select * from table_name except select top 
 (numbers of rows - how many rows you want)* from table_name
Run Code Online (Sandbox Code Playgroud)

这些陈述有效,但方式不同.感谢你们.

 select * from Products except select top (77-10) * from Products
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以获得最后10行,但订单将显示为descnding方式

select top 10 * from products
 order by productId desc 
Run Code Online (Sandbox Code Playgroud)
 select * from products
 where productid in (select top 10 productID from products)
 order by productID desc
Run Code Online (Sandbox Code Playgroud)
 select * from products where productID not in 
 (select top((select COUNT(*) from products ) -10 )productID from products)
Run Code Online (Sandbox Code Playgroud)


Hak*_*tık 7

以一种非常通用的方式来支持SQL服务器

SELECT TOP(N) *
FROM tbl_name
ORDER BY tbl_id DESC
Run Code Online (Sandbox Code Playgroud)

并且对于性能,它还不错(在服务器机器上超过10,000条记录不到一秒钟)

  • 好吧,10'000 条记录并不是您应该关心性能的地方。当您开始谈论数百万条记录时,您可以开始考虑性能 (2认同)

Ada*_*Dev 6

"Id"被编入索引吗?如果没有,这是一件很重要的事情(我怀疑它已被编入索引).

此外,您是否需要返回所有列?如果你只需要一个较小的列子集,你可以获得速度的实质性改进,这些列可以由ID列上的索引完全满足 - 例如,如果你在Id列上有一个NONCLUSTERED索引,没有其他如果字段包含在索引中,则必须对聚集索引进行查找以实际返回其余列,这可能会占用查询的大量成本.如果它是一个CLUSTERED索引,或者包含要在查询中返回的所有其他字段的NONCLUSTERED索引,那么你应该没问题.


小智 6

select * from (select top 6 * from vwTable order by Hours desc) T order by Hours
Run Code Online (Sandbox Code Playgroud)


Ard*_*oli 6

首先,你最多得到记录数

 Declare @TableRowsCount Int
 select @TableRowsCount= COUNT(*) from <Your_Table>
Run Code Online (Sandbox Code Playgroud)

然后 :

在SQL Server 2012中

SELECT *
FROM  <Your_Table> As L
ORDER BY L.<your Field>
OFFSET <@TableRowsCount-@N> ROWS
FETCH NEXT @N ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)

在SQL Server 2008中

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