2013-03-20 5 views
0

У меня есть мнение, которое может содержать более чем одну строку, глядя, как это:SQL Server 2005 ВЫБРАТЬ TOP 1 из VIEW возвращает последнюю строку

[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 

Но это ВСЕГДА возвращает LAST строку вида.

Фактически, если я просто запускаю подзадачу самостоятельно, я получаю только последнюю строку.
С 3 строками в представлении TOP 2 возвращает строки FIRST и THIRD по порядку. С 4 строками он возвращает верхнюю 3 по порядку. Тем не менее, верхняя часть 1 возвращает последнее. DERP?!?

Это работает ..

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 

.. но может кто-то сказать мне, почему первая ведет себя так fudgely и как делать то, что я хочу? Как поясняется в комментариях, нет значимой колонки, по которой я могу сделать заказ. Могу ли я заставить порядок, в который вставлены строки, быть порядком, в котором они возвращаются?

[EDIT] Я также заметил, что: select top 1 rate from ([view definition select]) также возвращает правильное время значения и снова [/ EDIT]

+4

Что вы определяете как 'last' row. Вы не заказываете свой результат. SQL Server не гарантирует, что заказ будет одинаковым при каждом выполнении запроса, таким образом, «TOP 1» может быть другой строкой каждый раз, когда вы выполняете запрос. – JodyT

+0

, который перешел мне в голову, но он никогда не меняется, кроме как я заметил. Конечно, я предполагаю, что последняя строка, вставленная в таблицу, будет последней строкой, которая, возможно, не так? Но если все это верно, то вставка в таблицу temp должна быть такой же ненадежной. Я полагаю, что, вероятно, первое место влияет на оптимизатор, и он делает некоторые фанки упорядочения на основе таблиц и объединяется в самом представлении? Тем не менее, я ожидаю, что метод temp table будет таким же ненадежным. Все, что сказал, для меня нет возможности сортировать эти данные, чтобы подделать порядок вставки (нет PK, нет дат и т. Д.) – JoeBrockhaus

+0

Если у вас нет столбцов (-ов) заказа, чтобы сообщить вам, какие из них были вставлены совсем недавно , откуда вы знаете, что он не возвращал неверные результаты в прошлом? – UnhandledExcepSean

ответ

0

Хотя не обязательно имеет смысл, что результаты запроса должны быть согласованными, в данном конкретном случае они так решили, что мы оставим его «как есть». В конечном итоге было бы лучше добавить столбец, но это был не вариант. Приложение, к которому это относится, скоро будет прекращено, и сервер базы данных не будет обновлен с SQL 2005.Мне не обязательно нравиться этот результат, но это то, что оно есть: пока оно не сломается, оно не будет исправлено. : -x

+1

Вернее, он не сломан достаточно, чтобы его можно было исправить. :) Одним из важных факторов является то, что точные последствия известны, если они когда-либо потерпят неудачу, о которых нельзя сказать обо всех клодах. – Guffa

1

То есть дизайн..

Если вы не укажете, как следует сортировать запрос, база данных может возвращать записи в любом удобном для вас порядке. Естественного порядка для таблицы, которая используется в качестве порядка сортировки по умолчанию.

Какой порядок на самом деле будет зависеть от того, как будет планироваться запрос, поэтому вы не можете даже полагаться на один и тот же запрос, дающий последовательный результат с течением времени, поскольку база данных будет собирать статистику о данных и может изменить способ запрос основан на этом.

Чтобы получить запись, которую вы ожидаете, вы просто должны указать, как вы хотите, чтобы они сортируются, например:

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

К сожалению, у меня нет столбца, по которому сортировка будет иметь смысл. Порядок создания продавцов или ставок (иначе, идентификаторы) не совпадает с порядком, в котором поставщики и ставки связаны друг с другом. к сожалению, таблица ассоциаций, в которой абстрагируется представление, не имеет ПК, никаких дат и т. д. - все, что мне нужно, это порядок, в котором данные были вставлены. Вы полагаете, что метод временной таблицы, который, кажется, работает, является случайностью? – JoeBrockhaus

+1

@JoeBrockhaus: Да, это просто случайность, когда вы получаете результат, ожидаемый при использовании временной таблицы. Если вы надежно хотите получить записи в том порядке, в котором они были добавлены, вы должны сохранить некоторую информацию об этом в таблице. – Guffa

+0

С одной стороны, это случайность, потому что она не должна быть последовательной. С другой стороны, это непротиворечиво, так что не очень вкусно. : -s – JoeBrockhaus

1

Я столкнулся с этой проблемой на запросе, который работал в течение многих лет. Мы обновили SQL Server, и внезапно неупорядоченный select top 1 не возвращал окончательную запись в таблицу. Мы просто добавили order by к select.

Насколько я понимаю, SQL Server обычно будет предоставлять результаты на основе кластеризованного индекса, если нет order by или исключен любой индекс, выбранный движком. Но это не гарантия определенного порядка.

Если у вас нет заказа, вы должны добавить его. Либо добавьте столбец, вставленный в дату, и по умолчанию укажите его значение GETDATE() или добавьте столбец identity. Это не поможет вам исторически, но оно решает проблему в будущем.

 Смежные вопросы

  • Нет связанных вопросов^_^