我可以做SELECT TOP(200)......但为什么不能BOTTOM(200)?
好吧,不要进入哲学我的意思是,我怎么能做相当于TOP(200)但相反(从底部开始,就像你期望BOTTOM做的那样......)?
答案 0 :(得分:91)
没必要。您可以使用ORDER BY
,只需将排序更改为DESC
即可获得相同的效果。
答案 1 :(得分:79)
SELECT
columns
FROM
(
SELECT TOP 200
columns
FROM
My_Table
ORDER BY
a_column DESC
) SQ
ORDER BY
a_column ASC
答案 2 :(得分:31)
抱歉,我认为我认为没有任何正确答案。
TOP
x函数以未定义的顺序显示记录。从该定义可以看出,BOTTOM
函数无法定义。
独立于任何索引或排序顺序。执行ORDER BY y DESC
时,首先获得y值最高的行。如果这是一个自动生成的ID,它应该显示最后添加到表中的记录,如其他答案中所建议的那样。但是:
TOP
函数正确的答案应该是没有,也不可能等同于TOP
来获得底行。
答案 3 :(得分:14)
从员工中选择底部1000
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
)
答案 4 :(得分:3)
目前接受的答案是" Justin Ethier"如#34; 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
我绝不会声称在所有情况下使用这个都是个好主意,但它可以提供理想的结果。
答案 5 :(得分:2)
您需要做的就是撤消ORDER BY
。添加或删除DESC
。
答案 6 :(得分:1)
排序另一种方式的问题是它通常不能很好地利用索引。如果您需要选择不在开头或结尾的行数,它也不是非常可扩展的。另一种方法如下。
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;
答案 7 :(得分:1)
“Tom H”上面的答案是正确的,它对我来说可以获得5行。
SELECT [KeyCol1], [KeyCol2], [Col3]
FROM
(SELECT TOP 5 [KeyCol1],
[KeyCol2],
[Col3]
FROM [dbo].[table_name]
ORDER BY [KeyCol1],[KeyCol2] DESC) SOME_ALAIS
ORDER BY [KeyCol1],[KeyCol2] ASC
感谢。
答案 8 :(得分:1)
似乎在解决方案中实现ORDER BY子句的任何答案都缺少这一点,或者实际上并不理解TOP返回给你的那些。
TOP返回无序查询结果集,该结果集将记录集限制为返回的前N个记录。 (从Oracle的角度来看,它类似于添加ROWNUM&lt;(N + 1)。
使用订单的任何解决方案,可能返回也由TOP子句返回的行(因为该数据集首先是无序的),具体取决于订单中使用的标准由
TOP的用处是,一旦数据集达到特定大小N,它就会停止提取行。无需获取所有数据,您就可以了解数据的样子。
要准确实现BOTTOM,需要获取无序的整个数据集,然后将数据集限制为最终的N条记录。如果你正在处理庞大的表格,这将不会特别有效。它也不一定会给你你所要求的想法。数据集的末尾可能不一定是“插入的最后一行”(并且可能不适用于大多数DML密集型应用程序)。
同样,不幸的是,在处理大型数据集时,实现ORDER BY的解决方案可能是灾难性的。如果我拥有10亿条记录并希望获得最后10条记录,那么订购10亿条记录并选择最后10条记录是非常愚蠢的。
这里的问题是,在将它与TOP进行比较时,BOTTOM没有我们想到的含义。
当一次又一次地插入,删除,插入,删除记录时,存储中会出现一些间隙,如果可能,稍后会插入行。但是我们经常看到,当我们选择TOP时,会出现作为排序数据,因为它可能是在表的存在的早期插入的。如果表没有经历多次删除,则可能出现进行排序。 (例如,创建日期可能与表创建本身一样早。)但实际情况是,如果这是一个删除量很大的表格,那么TOP N行可能看起来就不一样了。
所以 - 这里的底线(双关语意思)是那些要求BOTTOM N记录的人实际上并不知道他们要求的是什么。或者,至少,他们所要求的以及BOTTOM实际意味着什么并不是一回事。
所以 - 解决方案可能满足请求者的实际业务需求......但不符合成为BOTTOM的标准。
答案 9 :(得分:1)
SELECT TOP 10*from TABLE1 ORDER BY ID DESC
其中ID是TABLE1的主键。
答案 10 :(得分:0)
试试这个。
declare @floor int --this is the offset from the bottom, the number of results to exclude
declare @resultLimit int --the number of results actually retrieved for use
declare @total int --just adds them up, the total number of results fetched initially
--following is for gathering top 60 results total, then getting rid of top 50. We only keep the last 10
set @floor = 50
set @resultLimit = 10
set @total = @floor + @resultLimit
declare @tmp0 table(
--table body
)
declare @tmp1 table(
--table body
)
--this line will drop the wanted results from whatever table we're selecting from
insert into @tmp0
select Top @total --what to select (the where, from, etc)
--using floor, insert the part we don't want into the second tmp table
insert into @tmp1
select top @floor * from @tmp0
--using select except, exclude top x results from the query
select * from @tmp0
except
select * from @tmp1
答案 11 :(得分:0)
我已经提出了一个解决方案,并不需要您知道返回的行数。
例如,如果您想获取记录在表中的所有位置,除了最新的1(或2,或5或34)
SELECT *
FROM
(SELECT ROW_NUMBER() OVER (ORDER BY CreatedDate) AS Row, *
FROM Locations
WHERE UserId = 12345) AS SubQuery
WHERE Row > 1 -- or 2, or 5, or 34
答案 12 :(得分:0)
查询一个按降序排序的简单子查询,然后按同一列升序排序就可以了。
SELECT * FROM
(SELECT TOP 200 * FROM [table] t2 ORDER BY t2.[column] DESC) t1
ORDER BY t1.[column]
答案 13 :(得分:0)
首先,使用以下命令根据表的原始顺序在子查询中创建索引:
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
答案 14 :(得分:0)
您可以使用OFFSET FETCH子句。
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;
(用于Microsoft SQL Server)
官方文档: https://www.sqlservertutorial.net/sql-server-basics/sql-server-offset-fetch/