GÜNCELLEME sorgusundaki sütunları seçmek için CASE kullanılır mı?


13

CASEBir SELECTsorguda (Postgres) görüntülemek için hangi sütunları seçmek için kullanabilirsiniz , şöyle:

SELECT CASE WHEN val = 0 THEN column_x
            WHEN val = 1 THEN column_y
            ELSE 0
       END AS update, ...

UPDATEPostgres'te bir sorgu gerçekleştirirken benzer bir şey mümkün mü (yani hangi sütunların güncellenmesi gerektiğini seçin)? Bu konuda hiçbir şey bulamadığımı sanmıyorum, ama belki birisinin akıllı bir alternatifi vardır (bir prosedürü kullanmanın veya sütunun CASEdeğerine yeni bir değer atanıp atanmayacağını belirlemek için her sütunu güncellemenin yanı sıra mevcut olanı yeniden atama değeri). Kolay bir alternatif yoksa, elbette bunu bir cevap olarak kabul edeceğim.

Ek bilgi : Benim durumumda güncellenen 14 potansiyel sütun var, eşleşen satır başına sadece bir güncellenir (güncellenecek tablo sorguda başka bir ile birleştirilir). Güncellenecek satırların miktarı büyük olasılıkla değişir, düzinelerce veya yüzlerce olabilir. Birleştirme koşulları için endekslerin mevcut olduğuna inanıyorum.

Yanıtlar:


26

Bir sütunun güncellenmesi gerektiğini belirtirseniz, her zaman güncellenir, ancak koşullu olarak koyduğunuz değeri değiştirebilir ve koşullarınıza bağlı olarak orijinal değerleri geri koyabilirsiniz. Gibi bir şey:

UPDATE some_table
SET    column_x = CASE WHEN should_update_x THEN new_value_for_x ELSE column_x END
     , column_y = CASE WHEN should_update_y THEN new_value_for_y ELSE column_y END
     , column_z = CASE WHEN should_update_z THEN new_value_for_z ELSE column_z END
FROM   ...

Dolayısıyla, belirli bir sütunda güncelleme yapılması için koşullar doğru değilse, geçerli değeri geri beslersiniz.

Not Do eşleştirilmiş her satır olacak (tüm sütunlar zaten sahip oldukları değerlere set elde sonunda bile) bir güncelleme göreceksiniz sürece açıkça kapısı bir performans sorun olabilir sen ON ve cümlecikleri filtreleme bu durum, (orada olacak bir yazma, endeksler güncellenecek, uygun tetikleyiciler ateş edecek, ...) hafifletilmezse.


Güncellenen her şeyle ilgili ipucu için teşekkürler, eğer bu yavaşsa, @Colin'in Hart'ın birden fazla güncelleme ifadesine sahip olma önerisini alabilirim.
newenglander

ON ve WHERE yan tümcelerinizin, hiçbir değişikliğe ihtiyaç duyulmayan tüm satırları filtrelediğinden emin olarak bu sorunu tamamlayarak azaltabilirsiniz, ancak bu, hem SET yan tümcesinde hem de WHERE yan tümcesinde tüm koşullarınızın yinelenmesi anlamına gelebilir (daha basit bir genel denetim yoksa tüm bu koşullara% 100 eşdeğerdir). Bu noktada bu yöntem yine de daha verimli olabilir, ancak çoklu güncelleme yönteminin bakımı daha kolay olabilir.
David Spillett

Bir sütunu aynı değere güncellemenin de yinelemenin oluşturulmasına neden olacağını da unutmayın, bkz. Orainternals.wordpress.com/2010/11/04/…
Colin 't Hart

@Colin: Evet, herhangi bir güncelleme, alanların daha önce sahip oldukları değerlere sahip olması nedeniyle güncellenmesi nedeniyle esasen NoOps olan güncelleştirmeleri içeren DB'nin işlem günlüğünden geçecektir. Anlık bir performans sorunu potansiyelinin yanı sıra, çoğaltma, farklı yedeklemeler, günlük gönderimi vb. Kullanılırsa bu önemli bir faktör olabilir, çünkü ekstra satır güncelleme işlemleri bunlar için gereken alanı / bant genişliğini artıracaktır.
David Spillett

Her ikinize de ipuçları için teşekkürler, benim durumumda tek güncelleme bildirimi iyi çalıştı.
newenglander

5

Güncellenecek kaç farklı sütun kombinasyonunuz var? Tüm tablonun kaç satırı güncellenecek? Güncellenecek satırlara hızlı erişim için dizinler mevcut mu?

Bu soruların yanıtlarına bağlı olarak, güncellemek istediğiniz her sütun için bir tane olmak üzere birden çok güncelleme ifadesi yürütebilir ve koşulu o sütunun değerine güncellemenin nerede yantümcesine yerleştirebilirsiniz, böylece bu sütun sıfır satırları güncellenir değeri yanlış.

Küme temelli düşünün ve düşünün, güncellemenin birincil anahtar tarafından bulunan tek bir satırı güncellemesi gerektiğini varsaymayın.


Cevap için teşekkürler. Soruma biraz daha bilgi ekledim, umarım anlaşılabilir. Bu, birden fazla güncelleme bildirimi ile iyi bir alternatiftir (bir güncelleme bildirimini tercih ederim, ancak orada bir avantaj olduğunu görüyorum).
newenglander

Bu aradığım cevap olabilir ama güncelleme sütun_x = new_value_for_x nereye @val = 0 koymak istiyorsun. Böyle bir şey üzerinde deney yapabilirsiniz. Komik görünüyor. Val = 0, update_x = new_value_for_x vb. Güncellemelere başlarsa bunu yapmak daha kolay değildir
CashCow

-1
update Practicing  -- table you will be updating
 set email = case -- column you will be updating
    when FName = 'Glenn' then 'Ace@Assasin.com'
       when FName = 'Riddick' then 'fallguy@Drunk.com'
       when FName = 'Jeffrey' then 'sorcerer@wizcom'
       else email
    end

Bu güncelleme sadece tek bir sütun, asker ise koşullara bağlı olarak farklı sütunları nasıl güncelleyeceğini bilmek istiyor.
Colin 't Hart
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.