我可以使用SELECT TOP (200) ...,但为什么没有BOTTOM (200)呢?
好吧,不谈哲学,我的意思是,如何执行相当于TOP (200)的相反操作(从底部开始,就像你想要的BOTTOM一样...)?
我可以使用SELECT TOP (200) ...,但为什么没有BOTTOM (200)呢?
好吧,不谈哲学,我的意思是,如何执行相当于TOP (200)的相反操作(从底部开始,就像你想要的BOTTOM一样...)?
SELECT
columns
FROM
(
SELECT TOP 200
columns
FROM
My_Table
ORDER BY
a_column DESC
) SQ
ORDER BY
a_column ASC
这是不必要的。你可以使用ORDER BY
,并将排序方式改为DESC
来获得相同的效果。
很抱歉,但在我看来,我认为没有任何正确的答案。
TOP
x函数显示未定义顺序的记录。根据这个定义,无法定义BOTTOM
函数。
独立于任何索引或排序顺序。当您执行ORDER BY y DESC
时,将首先获取具有最高y值的行。如果这是自动生成的ID,则应该显示最后添加到表中的记录,就像其他答案中建议的那样。但是:
TOP
函数相比,它具有显着的性能影响正确的答案应该是不存在并且不能有与TOP
等价的方法来获取底部行。
从逻辑上讲,
BOTTOM (x) is all the records except TOP (n - x), where n is the count; x <= n
例如:选择Employee表的最后1000行:
在T-SQL中,
DECLARE
@bottom int,
@count int
SET @bottom = 1000
SET @count = (select COUNT(*) from Employee)
select * from Employee emp where emp.EmployeeID not in
(
SELECT TOP (@count-@bottom) Employee.EmployeeID FROM Employee
)
insert
语句,将行插入到一个大型未索引的表中。(在开始对其进行索引之前,我首先填充表格。)由于重新启动或其他原因,我失去了客户端会话,现在我想查看我的新添加的行是否存在其中。如果表的“底部”行是我最近添加的行之一,那么我知道操作已完成。如果“底部”行是其他内容,则没有保证,我必须扫描整个表以确保...但很可能通过快速检查“底部”来节省一些时间,就像您可以检查“顶部”一样。 - Ed Avis首先,在子查询中按照表的原始顺序创建索引,使用以下代码:
ROW_NUMBER () OVER (ORDER BY (SELECT NULL) ) AS RowIndex
然后按照主查询中创建的RowIndex
列,降序排序表格:
ORDER BY RowIndex DESC
TOP
关键字并指定所需行数即可: SELECT TOP 1 * --(or 2, or 5, or 34)
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL) ) AS RowIndex, *
FROM MyTable) AS SubQuery
ORDER BY RowIndex DESC
您只需要将ORDER BY
反转即可。添加或删除DESC
。
按另一种方式排序的问题在于它通常没有充分利用索引。如果您需要选择不在开头或结尾的多行,它也不太可扩展。另一种替代方法如下。
DECLARE @NumberOfRows int;
SET @NumberOfRows = (SELECT COUNT(*) FROM TheTable);
SELECT col1, col2,...
FROM (
SELECT col1, col2,..., ROW_NUMBER() OVER (ORDER BY col1) AS intRow
FROM TheTable
) AS T
WHERE intRow > @NumberOfRows - 20;
"Justin Ethier"的回答目前不正确,正如"Protector one"所指出的。
就我目前所见,没有其他回答或评论提供问题作者所需的BOTTOM(x)等效功能。
首先,让我们考虑需要使用此功能的情况:
SELECT * FROM Split('apple,orange,banana,apple,lime',',')
这将返回一个包含一列和五条记录的表格:
正如您所看到的:我们没有ID列;我们无法按返回的列排序;我们无法像对前两条记录那样使用标准SQL选择后两条记录。
以下是我提供解决方案的尝试:
SELECT * INTO #mytemptable FROM Split('apple,orange,banana,apple,lime',',')
ALTER TABLE #mytemptable ADD tempID INT IDENTITY
SELECT TOP 2 * FROM #mytemptable ORDER BY tempID DESC
DROP TABLE #mytemptable
这里是一个更完整的解决方案:
SELECT * INTO #mytemptable FROM Split('apple,orange,banana,apple,lime',',')
ALTER TABLE #mytemptable ADD tempID INT IDENTITY
DELETE FROM #mytemptable WHERE tempID <= ((SELECT COUNT(*) FROM #mytemptable) - 2)
ALTER TABLE #mytemptable DROP COLUMN tempID
SELECT * FROM #mytemptable
DROP TABLE #mytemptable
SELECT COUNT(1) FROM COHORT; --Number of results to expect
SELECT * FROM COHORT
ORDER BY ID
OFFSET 900 ROWS --Assuming you expect 1000 rows
FETCH NEXT 100 ROWS ONLY;