2011-08-07 14 views
10

Próbuję zaktualizować zestaw rekordów (boolean pól) w jednym zapytaniu, jeśli to możliwe.Warunki aktualizacji MySQL w jednym zapytaniu (UPDATE, SET & CASE)

Wejście pochodzi z numeracją stron sterowania radiowego, więc dana POST będzie mieć wartość dla strony identyfikatorów z true lub false wartości.

starałem się iść w tym kierunku:

UPDATE my_table 
    SET field = CASE 
     WHEN id IN (/* true ids */) THEN TRUE 
     WHEN id IN (/* false ids */) THEN FALSE 
    END 

Ale spowodowało to "prawdziwa id" wiersze aktualizowany do true i WSZYSTKIE inne wiersze zostały zaktualizowane do false.

Zakładam, że popełniłem poważny błąd składniowy, a może, że podchodzę do tego niepoprawnie.

Jakieś przemyślenia na temat rozwiązania?

+0

możliwe duplikat [MySQL] Aktualizacja przypadku pomocy (http://stackoverflow.com/questions/6734231/mysql- update-case-help) – nawfal

Odpowiedz

18

Czy nie zapomniałeś zrobić "ELSE" w przypadku sprawy?

UPDATE my_table 
    SET field = CASE 
     WHEN id IN (/* true ids */) THEN TRUE 
     WHEN id IN (/* false ids */) THEN FALSE 
     ELSE field=field 
    END 

Bez ELSE przyjmuję, że łańcuch oceny zatrzymuje się na końcu KIEDY i wykonuje tę aktualizację. Ponadto nie ograniczasz wierszy, które próbujesz zaktualizować; jeśli nie wykonasz ELSE, powinieneś przynajmniej poinformować aktualizację, aby aktualizowała tylko wiersze, które chcesz, a nie wszystkie wiersze (tak jak robisz). Spójrz na klauzuli WHERE poniżej:

UPDATE my_table 
     SET field = CASE 
      WHEN id IN (/* true ids */) THEN TRUE 
      WHEN id IN (/* false ids */) THEN FALSE 
     END 
    WHERE id in (true ids + false_ids) 
+0

Dzięki @Icarus - Drugi z zamieszczonych przez Ciebie rozwiązań jest doskonały. Podczas gdy pierwsza działa oczywiście, MySQL dopasowuje każdy wiersz w tabeli; wydaje się, że może powodować utratę wydajności w większych tabelach (* 10^6 wierszy lub więcej *), mimo że tylko aktualizuje wiersze, które uległy zmianie. Czy możesz rzucić trochę światła na to? (* warunek na unii wszystkich identyfikatorów docelowych jest wystarczająco dobrym rozwiązaniem, ale jestem po prostu ciekawy *) – Dan

+1

@TomcatExodus: Nie jestem pewien, czy rozumiem twoje pytanie, ale generalnie, jeśli masz aktualizację bez gdzie klauzula bazy danych prawie na pewno będzie musiała wykonać skanowanie tabeli i zaszkodzi wydajności, szczególnie na dużych stołach. Tak, tak, mając klauzula where tam powinna być szybsza, ale tylko wtedy, gdy kolumna id jest również indeksem. Jeśli tak nie jest, skanowanie tabeli jest nieuniknione. – Icarus

+0

Ok @Icarus - To właśnie miałem na myśli, kolumna "id" jest indeksowana. Miałem na myśli strumień wyjściowy; bez klauzuli "WHERE", dopasowuję kilka tysięcy wierszy, ale dotyczy to tylko garstki. Dopasowywane tysiące to pełne skanowanie tabeli, którego chciałbym uniknąć, i * uniknięto * poprzez zastosowanie klauzuli "WHERE", określającej tylko połączenie prawdziwych/fałszywych identyfikatorów. Chciałem tylko wyjaśnienia. Dzięki! – Dan

4

można uniknąć field = pole

update my_table 
    set field = case 
     when id in (....) then true 
     when id in (...) then false 
     else field 
    end 
+0

Dzięki @nick rulez - Na samym początku pole 'field = field' wydawało się dziwne (* field = field = field? *) – Dan