Как я могу обновить топ 100 записей на сервере SQL

394

Я хочу обновить первые 100 записей в SQL Server. У меня есть таблица T1с полями F1и F2. T1имеет 200 записей. Я хочу обновить F1поле в топ-100 записей. Как я могу обновить на основе TOP 100в SQL Server?

Раджеш
источник

Ответы:

685

Обратите внимание, скобки необходимы для операторов UPDATE:

update top (100) table1 set field1 = 1
Умайр Ахмед
источник
28
Любая идея, как использовать, order byа?
Джо Филлипс
8
@JoePhilllips Используйте ответ Мартина Смита для заказа
jjxtra
Однако это не 100 лучших записей, а просто 100 произвольно выбранных записей. В топ-100 будет включен порядок ранжирования записей.
Торстен Кеттнер
1
Это отвечает на вопрос «как задано», но ТОП не имеет смысла (и непредсказуемо) без некоторого ЗАКАЗА. Смотрите ответ ниже от Мартина Смита.
Энди Дж
1
кстати: скобки важны!
Simon_Weaver
300

Без ORDER BYсамой идеи TOPне имеет особого смысла. Вы должны иметь последовательное определение того, какое направление «вверх», а какое «вниз», чтобы концепция вершины имела смысл.

Тем не менее SQL Server допускает это, но не гарантирует детерминированный результат .

UPDATE TOPСинтаксис в общепринятом ответе не поддерживает ORDER BYположение , но можно получить детерминированную семантику здесь с помощью КТРА или производной таблицы , чтобы определить нужный порядок сортировки , как показано ниже.

;WITH CTE AS 
( 
SELECT TOP 100 * 
FROM T1 
ORDER BY F2 
) 
UPDATE CTE SET F1='foo'
Мартин Смит
источник
71
Вы говорите бессмысленно, но это не так. Я признаю, что / обычно /, когда вы используете TOPшансы, вы должны использовать это с ORDER BYтем, что вас интересует, это как "большинство" или "минимум" чего-то. Однако в других случаях вас может заинтересовать только одна подходящая запись. Как я сегодня! Мне нужно было исправить проблемы с данными (циклы) по одному. Весь процесс исправления включал сценарий БД, некоторое вмешательство пользователя и некоторые операции приложения. Нам было все равно, какая запись была обработана первой. Мы просто заботились о том, чтобы обрабатывать их по одному.
MetaFight
17
@MetaFight Но тогда у вас был бы WHEREпункт, чтобы исключить ранее обработанные записи. Вопрос в виде написанного и принятого ответа довольно бессмысленный. Кстати: для использования таблиц в качестве очереди это довольно полезная ссылка
Martin Smith
10
Мне нужно использовать top без порядка, чтобы я мог запустить асинхронный процесс. Предложение where не будет включать те, которые уже были обработаны, но я могу обрабатывать только очень много одновременно. Таким образом, он имеет вполне допустимый вариант использования.
Джефф Дэвис
4
@ Мартин Смит: Допустим, вы хотите обновить в пакетном режиме, скажем, 10000 за один раз. Похоже, это хорошее применение, и порядок не имеет значения. Как это "не имеет смысла"?
Джей Салливан
5
@ notfed Это тот же случай, который уже обсуждался до смерти в комментариях выше. Ваш запрос в этом случае не будет выглядеть так, как в принятом ответе, не так ли? Вам потребуется whereпредложение, чтобы избежать повторной обработки одних и тех же строк.
Мартин Смит
14

для тех, кто, как я до сих пор застрял с SQL Server 2000, SET ROWCOUNT {number};может быть использован до UPDATEзапроса

SET ROWCOUNT 100;
UPDATE Table SET ..;
SET ROWCOUNT 0;

ограничит обновление до 100 строк

Он устарел, по крайней мере, с SQL 2005, но с SQL 2017 он все еще работает. https://docs.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017

Клаудио Б
источник
1
SET ROWCOUNT влияет на триггеры, а также на обновляемую команду. Если вы установили каскадное удаление, транзакция может завершиться неудачно, если в дочерней таблице больше, чем количество строк дочерних строк.
EricI
С учетом сказанного, SET ROWCOUNT @RowCountParameter; допустимый синтаксис, тогда как SELECT TOP @RowCountParamter * FROM TableName недействителен. Если вам нужно сконфигурировать обновляемые строки, SET ROWCOUNT # в настоящее время является лучшим вариантом, если у вас нет дочерних таблиц с включенным каскадным удалением.
EricI
В SQL Server 2017 теперь можно использовать @variable в предложении TOP: docs.microsoft.com/en-us/sql/t-sql/queries/…
Александр Зарубкин
13
update tb set  f1=1 where id in (select top 100 id from tb where f1=0)
hyyxing
источник
4

Что еще круче, так это тот факт, что вы можете использовать встроенную табличную функцию, чтобы выбрать, какую (и сколько через TOP) строку (и) обновлять. Это:

UPDATE MyTable
SET Column1=@Value1
FROM tvfSelectLatestRowOfMyTableMatchingCriteria(@Param1,@Param2,@Param3)

Для табличной функции у вас есть что-то интересное, чтобы выбрать строку для обновления, например:

CREATE FUNCTION tvfSelectLatestRowOfMyTableMatchingCriteria
(
    @Param1 INT,
    @Param2 INT,
    @Param3 INT
)
RETURNS TABLE AS RETURN
(
    SELECT TOP(1) MyTable.*
    FROM MyTable
    JOIN MyOtherTable
      ON ...
    JOIN WhoKnowsWhatElse
      ON ...
    WHERE MyTable.SomeColumn=@Param1 AND ...
    ORDER BY MyTable.SomeDate DESC
)

... и в этом (по моему скромному мнению) истинная сила обновления только верхних выбранных строк детерминистически, в то же время упрощая синтаксис UPDATEоператора.

Михаил Гольдштейн
источник
0

Пытаться:

UPDATE Dispatch_Post
SET isSync = 1
WHERE ChallanNo 
IN (SELECT TOP 1000 ChallanNo FROM dbo.Dispatch_Post ORDER BY 
CreatedDate DESC)
Шахин Аль Кабир Митул
источник
0

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

UPDATE  TOP (500) T
SET     T.SomeColumn = 'Value'
FROM    SomeTable T
        INNER JOIN OtherTable O ON O.OtherTableFK = T.SomeTablePK
WHERE   T.SomeOtherColumn = 1
Вандерлей Пирес
источник