Как обновить и заказать с помощью MS SQL - PullRequest
48 голосов
/ 17 марта 2009

В идеале я хочу сделать это:

UPDATE TOP (10) messages SET status=10 WHERE status=0 ORDER BY priority DESC;

На английском языке: я хочу получить 10 лучших (статус = 0) сообщений из БД и заблокировать их (статус = 10). Сначала должно быть получено сообщение с более высоким приоритетом.

к сожалению, MS SQL не разрешает в заказе указание по порядку.

В любом случае, как это обойти?

Ответы [ 5 ]

97 голосов
/ 17 марта 2009
WITH    q AS
        (
        SELECT  TOP 10 *
        FROM    messages
        WHERE   status = 0
        ORDER BY
                priority DESC
        )
UPDATE  q
SET     status = 10
44 голосов
/ 17 марта 2009

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

UPDATE  messages 
SET status=10 
WHERE ID in (SELECT TOP (10) Id 
             FROM Table 
             WHERE status=0 
             ORDER BY priority DESC);
3 голосов
/ 06 июля 2016

Я должен предложить это как лучший подход - вы не всегда можете позволить себе роскошь поля идентификации:

UPDATE m
SET [status]=10
FROM (
  Select TOP (10) *
  FROM messages
  WHERE [status]=0
  ORDER BY [priority] DESC
) m

Вы также можете сделать подзапрос настолько сложным, насколько захотите - объединение нескольких таблиц и т. Д. *

Почему это лучше? Он не зависит от наличия поля идентификации (или любого другого уникального столбца) в таблице messages. Его можно использовать для обновления N верхних строк из любой таблицы, даже если эта таблица вообще не имеет уникального ключа.

1 голос
/ 17 марта 2009
UPDATE messages SET 
 status=10 
WHERE ID in (SELECT TOP (10) Id FROM Table WHERE status=0 ORDER BY priority DESC);
0 голосов
/ 17 марта 2009

Как указано в комментариях ниже, вы также можете использовать предложение SET ROWCOUNT, но только для SQL Server 2014 и старше.

SET ROWCOUNT 10

UPDATE messages
SET status = 10 
WHERE status = 0 

SET ROWCOUNT 0

Подробнее: http://msdn.microsoft.com/en-us/library/ms188774.aspx

Или с временной таблицей

DECLARE @t TABLE (id INT)
INSERT @t (id)
SELECT TOP 10 id
FROM messages
WHERE status = 0
ORDER BY priority DESC

UPDATE messages
SET status = 10
WHERE id IN (SELECT id FROM @t)
...