SQL Server SELECT LAST N Rows
这是一个已知的问题,但我找到的最佳解决方案是:
1 2 3 | SELECT TOP N * FROM MyTable ORDER BY Id DESC |
我有一张有很多行的桌子。使用该查询不是一种可能性,因为它需要很多时间。那么,如何在不使用order by的情况下选择最后n行呢?
编辑
抱歉,重复了这个问题
可以使SQL Server使用此SQL选择最后n行:
1 | SELECT * FROM tbl_name ORDER BY id DESC LIMIT N; |
我测试了Jonvd的代码,但发现它非常慢,6秒。
这段代码花了0秒。
1 2 3 | SELECT TOP(5) ORDERID, CUSTOMERID, OrderDate FROM Orders WHERE EmployeeID=5 ORDER BY OrderDate DESC |
您也可以通过使用按分区的行数功能来实现这一点。这里有一个很好的例子:
I am using the Orders table of the Northwind database... Now let us retrieve the Last 5 orders placed by Employee 5:
1
2
3
4
5
6
7
8
9 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
号
如果要从表中选择最后的行数。
语法如下
1 2 | SELECT * FROM TABLE_NAME EXCEPT SELECT top (numbers OF ROWS - how many ROWS you want)* FROM TABLE_NAME |
这些说法有效,但方式不同。谢谢你们。
1 | SELECT * FROM Products EXCEPT SELECT top (77-10) * FROM Products |
。
这样,您可以得到最后10行,但顺序将显示降序方式。
1 2 | SELECT top 10 * FROM products ORDER BY productId DESC |
。
1 2 3 | SELECT * FROM products WHERE productid IN (SELECT top 10 productID FROM products) ORDER BY productID DESC |
1 2 | SELECT * FROM products WHERE productID NOT IN (SELECT top((SELECT COUNT(*) FROM products ) -10 )productID FROM products) |
。
"id"被索引了吗?如果没有,这是一件重要的事情要做(我怀疑它已经被索引了)。
另外,是否需要返回所有列?如果您实际上只需要ID列上的索引能够完全满足的列的较小子集(例如,如果ID列上有一个非聚集索引,索引中不包含其他字段),那么您可能会在速度上得到很大的提高,然后它将不得不对聚集索引进行查找,以实际获得T。他返回其余的列,这可能会构成查询的大量成本。如果它是聚集索引,或者是包含查询中要返回的所有其他字段的非聚集索引,那么应该可以。
以非常一般的方式,为了支持SQL Server,这里是
1 2 3 | SELECT TOP(N) * FROM tbl_name ORDER BY tbl_id DESC |
号
性能还不错(服务器上10000多条记录不到一秒钟)
首先,你最多从
1 2 | DECLARE @TableRowsCount INT SELECT @TableRowsCount= COUNT(*) FROM <Your_Table> |
号
然后:
在SQL Server 2012中
1 2 3 4 5 | SELECT * FROM <Your_Table> AS L ORDER BY L.<your Field> OFFSET <@TableRowsCount-@N> ROWS FETCH NEXT @N ROWS ONLY; |
号
在SQL Server 2008中
1 2 3 4 5 6 7 8 | SELECT * FROM ( SELECT ROW_NUMBER() OVER(ORDER BY ID) AS sequencenumber, * FROM <Your_Table> ORDER BY <your Field> ) AS TempTable WHERE sequencenumber > @TableRowsCount-@N |
号
这里有一些没有
1 | SELECT * FROM tbl_name EXCEPT SELECT top L-N * FROM tbl_name |
。
如前所述,返回哪些行是未定义的。
编辑:这实际上是狗慢。真的没有价值。
1 | SELECT * FROM (SELECT top 6 * FROM vwTable ORDER BY Hours DESC) T ORDER BY Hours |
在查询结束时使用DESC和ORDERBY获取最后一个值。
此查询以正确的顺序返回最后n行,但性能较差
1 2 3 4 5 6 7 | SELECT * FROM ( SELECT top N * FROM TableName t ORDER BY t.[Id] DESC ) AS temp ORDER BY temp.[Id] |
号
这可能不太适合这个问题,但是…
抵消条款那个文档链接指向Postgres;我不知道这是否适用于Sybase/MS SQL Server。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 |
号
我用来查询非常大的表中最新的行(1亿多行或10亿多行)的一种技术将查询限制为"读取"最近行中最新的"n"百分比。这是真实世界的应用程序,例如,我对非历史最近的天气数据、最近的新闻提要搜索或最近的GPS位置数据点数据执行此操作。
例如,如果您确定您的行位于表的最新前5%中,那么这是一个巨大的性能改进。这样,即使表上有索引,它也会进一步限制表中具有1亿或10亿行的行的可能性仅为5%。尤其是当旧数据需要物理磁盘读取,而不仅仅是逻辑内存读取时。
这比选择top percent limit更有效,因为它不选择行,只限制要搜索的数据部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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' |
号
不使用
1 2 | 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) |
号
尝试使用
1 2 3 4 5 | SELECT * FROM clientDetails EXCEPT (SELECT TOP (numbers OF ROWS - how many ROWS you want) * FROM clientDetails) |
。