如何使用ms sql更新和订购

Toa*_*oad 49 sql t-sql sql-server sql-order-by sql-update

理想情况下我想这样做:

UPDATE TOP (10) messages SET status=10 WHERE status=0 ORDER BY priority DESC;
Run Code Online (Sandbox Code Playgroud)

英文:我想从数据库中获取前10个可用(状态= 0)消息并锁定它们(状态= 10).应首先获得具有更高优先级的消息.

遗憾的是,MS SQL不允许更新中的order by子句.

无论如何如何规避这个?

Qua*_*noi 102

WITH    q AS
        (
        SELECT  TOP 10 *
        FROM    messages
        WHERE   status = 0
        ORDER BY
                priority DESC
        )
UPDATE  q
SET     status = 10
Run Code Online (Sandbox Code Playgroud)

  • 这实际上是首选答案,而不是被接受的答案. (4认同)
  • 对于CTE来说+1,这样做可以在使用OUTPUT子句时为我删除连接 (2认同)
  • @xkingpin:CTE是原子的. (2认同)

小智 43

您可以执行子查询,首先获取按优先级排序的前10个的ID,然后更新该子查询上的ID:

UPDATE  messages 
SET status=10 
WHERE ID in (SELECT TOP (10) Id 
             FROM Table 
             WHERE status=0 
             ORDER BY priority DESC);
Run Code Online (Sandbox Code Playgroud)

  • 实际上查询不正确.... order by子句不能在子查询中使用,除非也给出了TOP.(这是SQL引擎所说的).所以正确的查询应该是:UPDATE消息SET status = 10 WHERE ID in(SELECT TOP(10)Id FROM Table WHERE status = 0 ORDER BY priority DESC); (7认同)

mfa*_*ino 6

我必须提供一个更好的方法 - 您并不总是拥有身份字段的奢侈:

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

您还可以根据需要使子查询变得复杂 - 加入多个表等...

为什么这样更好?它不依赖于表中标识字段(或任何其他唯一列)的存在messages。它可用于更新任何表的前 N ​​行,即使该表根本没有唯一键。

  • 如果您不花时间尝试理解它,我对我的答案的反对票并不感到惊讶。我的答案与 dotjoe 的答案不同 - 以及这里的大多数其他答案 - 因为其他答案假设表有一个标识字段(...其中 ID IN...)。您不能总是假设该表将具有标识字段。当您的表中没有 ID 字段时,我提供了一种替代方法。请在投票之前尝试理解答案。 (2认同)