如何选择最底行?

Met*_*uru 92 sql database sql-server select keyword

我可以做SELECT TOP(200)......但为什么BOTTOM(200)呢?

好吧,不要进入哲学我的意思是,我怎么能做相当于TOP(200)但相反(从底部开始,就像你期望BOTTOM做的那样......)?

Jus*_*ier 91

这是不必要的.您可以使用a ORDER BY并只更改排序DESC以获得相同的效果.

  • 如果你的桌子上没有ORDER BY的索引怎么办? (11认同)
  • 使用DESC将返回最后N行,但返回的行也将与前N行的顺序相反. (8认同)
  • @Justin:想象一下只有一列,包含varchar值.ORDER BY将按字母顺序排序,这可能(可能)不是我们想要的. (7认同)
  • 谷歌说了同样的话,现在有9个人同意,对我来说足够好了,谢谢:D (3认同)
  • Tom H.是正确的anwser,否则,您的行将按相反的顺序排列. (3认同)

Tom*_*m H 82

SELECT
    columns
FROM
(
     SELECT TOP 200
          columns
     FROM
          My_Table
     ORDER BY
          a_column DESC
) SQ
ORDER BY
     a_column ASC
Run Code Online (Sandbox Code Playgroud)

  • 如果要以A-> Z顺序返回行,但是在Z-> A顺序中选择前200,这是一种方法.其他答案,建议只更改ORDER BY将不会返回问题中描述的相同结果,因为它们将无序(除非顺序无关紧要,OP没有说). (14认同)
  • @Tom H.不得不考虑几秒钟你的意思(我已经14小时了).起初我无法通过答案看到你和订单之间的区别,但现在我可以.所以+1. (3认同)
  • 你为什么使用派生表? (2认同)

Mar*_*ger 36

对不起,但我认为我认为没有看到任何正确的答案.

TOPX功能显示在未确定的订单记录.从该定义可以看出,BOTTOM无法定义函数.

独立于任何索引或排序顺序.当你这样做时,ORDER BY y DESC首先得到y值最高的行.如果这是一个自动生成的ID,它应该显示最后添加到表中的记录,如其他答案中所建议的那样.然而:

  • 这仅在存在自动生成的id列时才有效
  • 如果将其与TOP功能进行比较,则会对性能产生重大影响

正确的答案应该是没有,也不可能等同TOP于获得底行.

  • TOP与将项添加到表中的顺序无关,它只是表示"提供与我的查询匹配的前X条记录" (4认同)
  • 我同意卢克的观点.根据定义,数据库表是无序的.当select语句没有ORDER BY子句时,不应该依赖于RDBMS提供的顺序.[在wiki上阅读](http://en.wikipedia.org/wiki/Table_%28database%29#Tables_versus_relations)_但是,除非在SELECT中指定了ORDER BY子句,否则数据库系统不保证行的任何排序查询表的语句._ (4认同)
  • 没错,似乎没有等效的,只是解决方法. (3认同)
  • 是的,它会为您提供记录添加到表中的与您的查询匹配的记录. (3认同)
  • 我同意这个答案,但在实践中[汤姆的答案](http://stackoverflow.com/a/1876620/2436175)解决了所有实际用途的问题. (2认同)

Sha*_*uti 16

从员工中选择Bottom 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
)
Run Code Online (Sandbox Code Playgroud)

  • bummi,你是对的,但是这个答案是正确的.选择TOP本身在理论上是"随机的",这是Select BOTTOM的正确实现.在5000个记录的表中,底部1000是除了前4000之外的所有内容. (5认同)
  • 你好,shadi2014,如果不使用“ORDER BY”,你的结果将是随机的。 (2认同)

小智 10

似乎在解决方案中实现 ORDER BY 子句的任何答案都没有抓住重点,或者实际上并不了解 TOP 返回给您的内容。

TOP 返回一个无序查询结果集,该结果集将记录集限制为返回的前 N ​​条记录。(从 Oracle 的角度来看,它类似于添加一个 where ROWNUM < (N+1)。

任何使用顺序的解决方案都可能返回也由 TOP 子句返回的行(因为该数据集首先是无序的),具体取决于顺序中使用的条件

TOP 的用处在于,一旦数据集达到特定大小 N,它就会停止获取行。您无需获取所有数据即可了解数据的外观。

为了准确地实现 BOTTOM,它需要无序地获取整个数据集,然后将数据集限制为最后的 N 条记录。如果您正在处理大表,这将不会特别有效。它也不一定会给你你认为你要求的东西。数据集的结尾可能不一定是“最后插入的行”(对于大多数 DML 密集型应用程序可能不会)。

同样,不幸的是,实现 ORDER BY 的解决方案在处理大型数据集时可能是灾难性的。如果我有 100 亿条记录并且想要最后 10 条记录,那么订购 100 亿条记录并选择最后 10 条记录是非常愚蠢的。

这里的问题是,当与 TOP 比较时,BOTTOM 没有我们想到的含义。

当记录被一遍遍地插入、删除、插入、删除时,存储中会出现一些间隙,然后,如果可能的话,将插入行。但是我们经常看到,当我们选择 TOP 时,似乎是排序的数据,因为它可能在表存在的早期就已经插入了。如果表没有经历很多删除,它可能看起来是有序的。(例如,创建日期可能与表创建本身的时间一样早)。但实际情况是,如果这是一个需要大量删除的表,则 TOP N 行可能根本不是这样。

所以 - 这里的底线(双关语)是要求 BOTTOM N 记录的人实际上并不知道他们在要求什么。或者,至少,他们的要求和 BOTTOM 的实际含义不是一回事。

所以——该解决方案可能满足请求者的实际业务需求……但不符合作为底层的标准。

  • 很好的解释。支持对这个话题有更多的了解。 (3认同)