2011-08-07 27 views
10

Mümkünse, bir kayıt kümesini (boolean alanları) tek bir sorguda güncelleştirmeye çalışıyorum.Bir sorguda MySQL güncelleştirme koşulları (UPDATE, SET & CASE)

Girdi paginated radyo denetimlerinden geliyor, bu nedenle verilen bir POST, sayfanın true veya false değeriyle kimlik değerlerine sahip olacaktır.

bu yönde gitmeye çalışıyordum:

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

Ama bu "gerçek kimliği" satırları true şekilde güncellenmektedir sonuçlandı ve TÜM diğer satırlar false olarak güncellenmiştir.

Ben bazı brüt sözdizimsel hata yaptık, ya da belki ben yanlış bu yaklaşıyorum varsayalım.

Çözüm üzerinde herhangi bir düşünce var mı?

+0

olası yinelenen http://stackoverflow.com/questions/6734231/mysql-: Aşağıdaki WHERE yan tümcesi bak update-case-help) – nawfal

cevap

18

Durum bildirisinde "ELSE" yapmayı unutmadınız mı? ELSE olmadan

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

, ben değerlendirme zinciri sonunda durur ZAMAN ve bu güncelleştirmeyi yürütür varsayalım. Ayrıca, güncellemeye çalıştığınız satırları sınırlamıyorsunuz; Eğer ELSE'yi yapmazsanız, en azından güncellemeyi sadece istediğiniz satırları güncellemeyi ve tüm satırları (yaptığınız gibi) güncellememelisiniz.

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

Teşekkürler @Icarus - Gönderdiğiniz ikinci çözüm mükemmel. Birincisi elbette çalışsa da, MySQL tablonun her sırasına denk geliyor; Bu, daha büyük tablolarda (* 10^6 satır ya da daha fazla *) performans kaybına neden olmakla birlikte, sadece değişmiş olan satırları güncellemesine rağmen. Buna biraz ışık tutabilir misin? (* tüm hedeflenen ID'lerin birleşimindeki durum yeterince temiz bir çözümdür, ama sadece merak ediyorum *) – Dan

+1

@TomcatExodus: Sorunuzu tam olarak anladığımdan emin değilim, ancak genel olarak, nerede veritabanı motoru hemen hemen kesinlikle bir tablo taraması yapmak zorunda kalacak ve özellikle büyük masalarda performansa zarar verecek. Yani evet, burada bulunan tümcenin daha hızlı olması gerekir, ancak sadece id sütunu bir dizin ise. Değilse, tablo taraması kaçınılmazdır. – Icarus

+0

Ok @Icarus - Ben kastediyorum, 'id' sütunu endeksli. Çıkış akışına atıfta bulunuyordum; WHERE fıkrası olmadan birkaç binlerce satır eşleşir, ancak yalnızca bir avuç etkilenir. Eşleştirilen binlerce, kaçınmak istediğim tam tablo taramasıdır ve * yalnızca bir * WHERE cümlesi uygulayarak kaçınılmakta, yalnızca doğru/yanlış kimliklerin bir birleşimi belirtilmektedir. Sadece biraz açıklama istedi. Teşekkürler! – Dan

4

Sen önleyebilirsiniz alan = alan

update my_table 
    set field = case 
     when id in (....) then true 
     when id in (...) then false 
     else field 
    end 
[MySQL güncelleme vaka yardım] (içinde
+0

Teşekkürler @nick rulez - 'field = alan' ilk bakışta da garip görünüyordu (* field = field = field? *) – Dan