質問

I have a view that may contain more than one row, looking like this:

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

In a SPROC, I need to set a param equal to the value of the first column from the first row of the view. something like this:

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

But this ALWAYS returns the LAST row of the view.

In fact, if I simply run the subselect by itself, I only get the last row.
With 3 rows in the view, TOP 2 returns the FIRST and THIRD rows in order. With 4 rows, it's returning the top 3 in order. Yet still top 1 is returning the last. DERP?!?

This works..

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

.. but can someone tell me why the first behaves so fudgely and how to do what I want? As explained in the comments, there is no meaningful column by which I can do an order by. Can I force the order in which rows are inserted to be the order in which they are returned?

[EDIT] I've also noticed that: select top 1 rate from ([view definition select]) also returns the correct values time and again.[/EDIT]

役に立ちましたか?

解決 3

While it doesn't necessarily make sense that the results of the query should be consistent, in this particular instance they are so we decided to leave it 'as is'. Ultimately it would be best to add a column, but this was not an option. The application this belongs to is slated to be discontinued sometime soon and the database server will not be upgraded from SQL 2005. I don't necessarily like this outcome, but it is what it is: until it breaks it shall not be fixed. :-x

他のヒント

That is by design.

If you don't specify how the query should be sorted, the database is free to return the records in any order that is convenient. There is no natural order for a table that is used as default sort order.

What the order will actually be depends on how the query is planned, so you can't even rely on the same query giving a consistent result over time, as the database will gather statistics about the data and may change how the query is planned based on that.

To get the record that you expect, you simply have to specify how you want them sorted, for example:

select top 1 rate
from vendor_view
where vendorID = 123
order by rate

I ran into this problem on a query that had worked for years. We upgraded SQL Server and all of a sudden, an unordered select top 1 was not returning the final record in a table. We simply added an order by to the select.

My understanding is that SQL Server normally will generally provide you the results based on the clustered index if no order by is provided OR off of whatever index is picked by the engine. But, this is not a guarantee of a certain order.

If you don't have something to order off of, you need to add it. Either add a date inserted column and default it to GETDATE() or add an identity column. It won't help you historically, but it addresses the issue going forward.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top