0

我有一个可能包含多行的视图,如下所示:

[rate] | [vendorID]
 8374       1234
 6523       4321
 5234       9374

在 SPROC 中,我需要设置一个参数,该参数等于视图第一行中第一列的值。像这样的东西:

DECLARE @rate int;
SET @rate = (select top 1 rate from vendor_view where vendorID = 123)
SELECT @rate

但这总是返回视图的最后一行。

事实上,如果我只是自己运行子选择,我只会得到最后一行。
视图中有 3 行,TOP 2 按顺序返回 FIRST 和 THIRD 行。有 4 行,它按顺序返回前 3 行。然而,前 1 名仍然是最后一名。德普?!?

这有效..

DECLARE @rate int;

CREATE TABLE #temp (vRate int)
INSERT INTO  #temp (vRate) (select rate from vendor_view where vendorID = 123)

SET @rate = (select top 1 vRate from #temp)
SELECT @rate

DROP TABLE #temp

..但是有人可以告诉我为什么第一个表现得如此愚蠢以及如何做我想做的事?正如评论中所解释的,没有任何有意义的列可以用来进行排序。我可以强制插入行的顺序为返回的顺序吗?

[编辑] 我还注意到:select top 1 rate from ([view definition select])也一次又一次地返回正确的值。[/编辑]

4

3 回答 3

1

这是设计使然。

如果您没有指定查询的排序方式,数据库可以自由地以任何方便的顺序返回记录。用作默认排序顺序的表没有自然顺序。

实际的顺序取决于查询的计划方式,因此您甚至不能依赖同一个查询随着时间的推移提供一致的结果,因为数据库将收集有关数据的统计信息并可能改变查询的计划方式在那。

要获得您期望的记录,您只需指定您希望它们如何排序,例如:

select top 1 rate
from vendor_view
where vendorID = 123
order by rate
于 2013-03-20T23:46:16.777 回答
1

我在一个已经工作多年的查询中遇到了这个问题。我们升级了 SQL Server,突然之间,无序select top 1没有返回表中的最终记录。我们只是order byselect.

order by我的理解是,如果没有提供或引擎选择的任何索引,SQL Server 通常会根据聚集索引为您提供结果。但是,这并不能保证一定的顺序。

如果您没有要订购的东西,则需要添加它。添加一个日期插入列并将其默认为GETDATE()或添加一identity列。从历史上看,它对您没有帮助,但它解决了未来的问题。

于 2013-12-27T17:02:00.783 回答
0

虽然查询的结果应该保持一致并不一定有意义,但在这种特殊情况下,它们是一致的,所以我们决定保持“原样”。最终最好添加一列,但这不是一个选项。这个属于的应用程序预计很快就会停止使用,并且数据库服务器不会从 SQL 2005 升级。我不一定喜欢这个结果,但它就是这样:除非它坏了,否则它不会被修复。:-X

于 2013-12-27T19:40:18.580 回答