2011-11-13 8 views
16

Używam programu SQL Server do zamiany dwóch wartości w dwóch wierszach. Pokażę:Instrukcja SQL UPDATE do przełączania dwóch wartości w dwóch wierszach

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

Say, muszę zamienić [ord] Numery dla "Pete" i "Steve", aby uczynić tę tabelę być tak:

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

wydaje się to trywialne Zadanie, ale nie mogę napisać dla niego instrukcji SQL UPDATE.

Odpowiedz

19

Jeśli 'Peter' i 'Steve' są unikatowe w tabeli, będzie to zrobić:

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

lub (poprawiona przez @Erwin):

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

Zmieniono umysł. Testowałem i działa również z MIN + MAX. –

+0

Co chciałem napisać na początek: +1 za rozwiązanie tego z agregacją. Chciałem to również zrobić, ale poddałem się, ponieważ nie mogłem znaleźć odpowiednika [array_agg()] (http://www.postgresql.org/docs/9.1/interactive/functions-aggregate.html) w tSQL . –

+0

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

4

Użyj CASE wyrażenie:

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

To tylko uproszczony podzestaw problemu. Zakłada, że ​​najpierw wyszukujesz 'numer porządkowy' Pete'a i Steve'a i budujesz zapytanie z wynikami. –

+0

Tak, oczywiście, nie próbuję tego zakodować. Dzięki za próbę, chociaż ... – ahmd0

+0

@ ahmd0: Wybacz, twoje pytanie nie wyjaśniło. –

7

To jest bardzo podobny do wcześniejszego pytania: SQL to move rows up or down in two-table arrangement
I przygotował kolejną demo on data.stackexchange.com dla Ciebie.

Edytuj: konfiguracja jest teraz uproszczona, więc odpowiednio uprościliśmy swoje zapytanie.

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; 

Ta kwerenda aktualizuje się tylko, jeśli można znaleźć oba wiersze i nie robi nic innego.

+1

Haha. Wiesz, wysłałem to pytanie, aby lepiej zrozumieć twój drugi post.)) Teraz wiem, co masz na myśli z tym kodem. Dzięki jeszcze raz. Niestety tym razem dałbym "odpowiedź" na powyższy ypercube. To bardzo zgrabne rozwiązanie z MAX/MAX lub SUM. – ahmd0

+0

@ ahmd0: Cóż, zgadzam się. Wzniosłem to sam. :) min/max, btw., nie max/max. Zabawne, miałem ten sam mixup ... –

+0

Ups. Nie mogę go teraz edytować ... – 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') 

można łatwo zastąpić 'Pete' i 'Steve' z innymi nazwami ...

+0

To działałoby w tym przykładzie. Dzięki. – ahmd0

Powiązane problemy