Cómo actualizar y ordenar usando ms sql
-
19-08-2019 - |
Pregunta
Idealmente quiero hacer esto:
UPDATE TOP (10) messages SET status=10 WHERE status=0 ORDER BY priority DESC;
En inglés: quiero obtener los 10 mejores mensajes disponibles (estado = 0) del DB y bloquearlos (estado = 10). Primero se debe recibir un mensaje con mayor prioridad.
desafortunadamente MS SQL no permite una orden por cláusula en la actualización.
De todos modos, ¿cómo evitar esto?
Solución
Puede hacer una subconsulta donde primero obtiene los ID de los 10 principales ordenados por prioridad y luego actualiza los que están en esa subconsulta:
UPDATE messages
SET status=10
WHERE ID in (SELECT TOP (10) Id
FROM Table
WHERE status=0
ORDER BY priority DESC);
Otros consejos
WITH q AS
(
SELECT TOP 10 *
FROM messages
WHERE status = 0
ORDER BY
priority DESC
)
UPDATE q
SET status = 10
Tengo que ofrecer esto como un mejor enfoque: no siempre tiene el lujo de un campo de identidad:
UPDATE m
SET [status]=10
FROM (
Select TOP (10) *
FROM messages
WHERE [status]=0
ORDER BY [priority] DESC
) m
También puede hacer que la subconsulta sea tan complicada como desee: unir varias tablas, etc. ...
¿Por qué es esto mejor? No se basa en la presencia de un campo de identidad (o cualquier otra columna única) en la tabla messages
. Se puede usar para actualizar las N filas superiores de cualquier tabla, incluso si esa tabla no tiene una clave única en absoluto.
UPDATE messages SET
status=10
WHERE ID in (SELECT TOP (10) Id FROM Table WHERE status=0 ORDER BY priority DESC);
Como se indica en los comentarios a continuación, también puede usar la cláusula SET ROWCOUNT, pero solo para SQL Server 2014 y versiones anteriores.
SET ROWCOUNT 10
UPDATE messages
SET status = 10
WHERE status = 0
SET ROWCOUNT 0
Más información: http://msdn.microsoft.com/en- us / library / ms188774.aspx
O con una tabla temporal
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)