2011-11-13 20 views
16

Estoy usando SQL Server para intercambiar dos valores en dos filas. Let me show:instrucción SQL UPDATE para cambiar dos valores en dos filas

[ord] [name] 
1  John 
4  Jack 
7  Pete 
9  Steve 
11 Mary 

Say, necesito intercambiar números [ord] para "Pete" y "Steve" para hacer esta tabla para ser así:

[ord] [name] 
1  John 
4  Jack 
9  Pete 
7  Steve 
11 Mary 

Este parece ser un trivial tarea pero parece que no puedo escribir una instrucción SQL UPDATE para ella.

Respuesta

19

Si 'Peter' y 'Steve' son únicos en su mesa, esto va a hacer:

UPDATE TableX 
SET ord = (SELECT MIN(ord) + MAX(ord) 
      FROM TableX 
      WHERE name IN ('Peter', 'Steve') 
     ) - ord 
WHERE name IN ('Peter', 'Steve') 

o (mejorada por @Erwin):

UPDATE TableX 
SET ord = (SELECT SUM(ord) 
      FROM TableX 
      WHERE name IN ('Peter', 'Steve') 
     ) - ord 
WHERE name IN ('Peter', 'Steve') 
+0

Mente cambiada nuevamente. Probé y funciona con MIN + MAX, también. –

+0

Lo que quería escribir para empezar: +1 para resolver esto con una agregación. Quería hacer eso también, pero me rendí, porque no pude encontrar un equivalente de [array_agg()] (http://www.postgresql.org/docs/9.1/interactive/functions-aggregate.html) en tSQL . –

+0

@ErwinBrandstetter: http://data.stackexchange.com/stackoverflow/q/117570/ –

4

utilizar una expresión CASE:

UPDATE yourtable 
SET [ord] = CASE [ord] WHEN 9 THEN 7 
         WHEN 7 THEN 9 END 
WHERE [ord] IN (7, 9) 
+1

Esto es solo un subconjunto simplificado del problema. Asume que usted consulta el 'número ordinal' de Pete y Steve primero y crea la consulta con los resultados. –

+0

Sí, obviamente no estoy tratando de codificarlo. Gracias por intentar, aunque ... – ahmd0

+0

@ ahmd0: Lo siento, su pregunta no lo dejó en claro. –

7

Esto es muy similar a la anterior pregunta: SQL to move rows up or down in two-table arrangement
me preparó otra demo on data.stackexchange.com para usted.

Editar: la configuración se simplifica ahora, por lo que simplifiqué mi consulta en consecuencia.

WITH x AS (SELECT name, ord FROM t WHERE name = 'Pete') -- must be unique! 
    , y AS (SELECT name, ord FROM t WHERE name = 'Steve') -- must be unique! 
UPDATE t 
SET ord = z.ord 
FROM (
    SELECT x.name, y.ord FROM x,y 
    UNION ALL 
    SELECT y.name, x.ord FROM x,y 
    ) z 
WHERE t.name = z.name; 

Esta consulta solo se actualiza si se pueden encontrar ambas filas y no hace nada de lo contrario.

+1

Haha. Ya sabes, publiqué esta pregunta para comprender mejor tu otra publicación.)) Ahora sé lo que querías decir con ese código. Gracias de nuevo. Desafortunadamente esta vez daría la "respuesta" a Ycubcube arriba. Es una solución muy buena con MAX/MAX o SUM. – ahmd0

+0

@ ahmd0: Bueno, estoy de acuerdo. Upvoted yo mismo. :) min/max, btw., no max/max. Es curioso, tuve la misma confusión ... –

+0

Vaya. No puedo editarlo ahora ... – ahmd0

0
BEGIN TRANSACTION 

UPDATE TABLENAME 
SET ord = 9 
where name = 'Pete' 

UPDATE TABLENAME 
SET ord = 7 
where name = 'Steve' 

COMMIT TRANSACTION 
3
UPDATE Table_1 
SET ord = 
    CASE name 
    WHEN 'Pete' THEN (SELECT ord FROM Table_1 WHERE name = 'Steve') 
    WHEN 'Steve' THEN (SELECT ord FROM Table_1 WHERE name = 'Pete') 
    END 
WHERE name IN ('Pete', 'Steve') 

Puede reemplazar fácilmente 'Pete' y 'Steve' con otros nombres ...

+0

Esto funcionaría en este ejemplo. Gracias. – ahmd0

Cuestiones relacionadas