T-SQL: Menggunakan CASE dalam pernyataan UPDATE untuk memperbarui kolom tertentu bergantung pada suatu kondisi

108

Saya bertanya-tanya apakah ini mungkin sama sekali. Saya ingin memperbarui kolom x jika kondisinya benar, jika tidak, kolom y akan diperbarui

UPDATE table SET
     (CASE (CONDITION) WHEN TRUE THEN columnx
                       ELSE columny
      END)
= 25

Saya telah mencari di mana-mana, mencoba beberapa hal dan tidak dapat menemukan solusi. Saya pikir itu tidak mungkin, tetapi saya pikir saya akan bertanya di sini dan melihat apakah ada yang pernah melakukannya sebelumnya. Terima kasih sebelumnya.

pqsk.dll
sumber
Dengan asumsi semua dalam tabel yang sama, ya. Anda selalu dapat menjalankannya dalam transaksi, & rollback saat terjadi kesalahan, untuk melihatnya sendiri.
OMG Ponies
Saya tidak yakin apa yang Anda maksud. Saya telah mencoba menempatkan persyaratan untuk kolom tersebut, tetapi tidak berhasil. Ini berfungsi untuk pernyataan pilih, tetapi tidak untuk pernyataan pembaruan. (Pilih (case (kondisi) ketika benar kemudian kolomx lain columny end) dari myTable .... pembaruan tidak berfungsi, dan saya dapat melihat mengapa. Tidak ada. Tampaknya bukan cara untuk membuatnya berhasil.
pqsk

Jawaban:

188

Anda tidak dapat menggunakan kondisi untuk mengubah struktur kueri Anda, hanya data yang terlibat. Anda bisa melakukan ini:

update table set
    columnx = (case when condition then 25 else columnx end),
    columny = (case when condition then columny else 25 end)

Ini secara semantik sama, tetapi perlu diingat bahwa kedua kolom akan selalu diperbarui . Ini mungkin tidak akan menimbulkan masalah bagi Anda, tetapi jika Anda memiliki volume transaksi yang tinggi, ini dapat menyebabkan masalah konkurensi.

Satu-satunya cara untuk melakukan spesifik apa yang Anda minta adalah dengan menggunakan SQL dinamis. Namun, ini adalah sesuatu yang saya dorong untuk Anda hindari. Solusi di atas hampir pasti akan cukup untuk apa yang Anda cari.

Adam Robinson
sumber
Saya setuju tentang SQL dinamis. Jadi, apakah data saya akan terpengaruh? Maksud saya, saya tidak ingin itu diubah untuk kondisi tertentu. Jadi itu hanya akan memasukkan kembali apa yang sudah ada di sana? Jumlah hit ke db mungkin tidak terlalu buruk.
pqsk
@pqsk: Ini tidak akan mempengaruhi data Anda, itu hanya harus memasukkan kembali apa yang sudah ada untuk kolom mana yang tidak akan terpengaruh.
Adam Robinson
Terima kasih. Saya akan pergi dengan ini. Sangat sederhana, bahkan manusia gua pun bisa melakukannya. ha ha.
pqsk
1
@AdamRobinson 1,5 tahun telah berlalu apakah Anda tahu beberapa cara yang lebih efisien untuk memperbarui hanya satu kolom
@Somebodyisintrouble: Satu-satunya cara untuk memperbarui satu kolom adalah dengan menggunakan kueri yang berbeda.
Adam Robinson
23
UPDATE  table
SET     columnx = CASE WHEN condition THEN 25 ELSE columnx END,
        columny = CASE WHEN condition THEN columny ELSE 25 END
Quassnoi
sumber
1
Apakah Anda baru saja menyalin jawaban Adam, atau ini diambil dari tempat lain? ha ha. Baru saja menyadarinya.
pqsk
1
@pqsk: Tanggapan kami berjarak ~ 1 menit, jadi saya membayangkan saya mengklik kirim sedikit lebih cepat;)
Adam Robinson
23
@pqsk: ya, saya baru saja menyalin tanggapan Adam, beberapa 23detik sebelum dia mempostingnya. Saya salah satu copypaster cepat!
Quassnoi
2
@pqsk: jika Anda meletakkan kursor di atas * min ago, ini akan menunjukkan kepada Anda waktu yang tepat saat diposkan.
Quassnoi
2
Agar adil, meskipun keduanya sama: jika Adam keluar setelah milik Anda, dia menjelaskan lebih banyak lagi. Itu sebabnya saya tandai dia sebagai jawabannya. Terimakasih Meskipun.
pqsk
4

masukkan deskripsi gambar di sini

Saya ingin mengubah atau memperbarui ContactNo saya ke 8018070999 di mana ada 8018070777 menggunakan pernyataan Kasus

update [Contacts] set contactNo=(case 
when contactNo=8018070777 then 8018070999
else
contactNo
end)

masukkan deskripsi gambar di sini

Debendra Dash
sumber
1
untuk ini mengapa tidak menggunakan kueri ini UPDATE [Kontak] SET contactNo = 8018070999 WHERE contactNo = 8018070777
NewGuy
4

Saya tahu ini adalah pertanyaan yang sangat lama, tetapi ini berhasil untuk saya:

UPDATE TABLE SET FIELD1 =
CASE 
WHEN FIELD1 = Condition1 THEN 'Result1'
WHEN FIELD1 = Condition2 THEN 'Result2'
WHEN FIELD1 = Condition3 THEN 'Result3'
END;

Salam

Victor Eduardo Salazar Ramirez
sumber
1

Saya tahu ini adalah pertanyaan yang sangat lama dan masalahnya ditandai sebagai sudah diperbaiki. Namun, jika seseorang dengan kasus seperti saya di mana tabel memicu pencatatan data pada peristiwa pembaruan, ini akan menyebabkan masalah. Kedua kolom akan mendapatkan pembaruan dan log akan membuat entri yang tidak berguna. Cara saya melakukannya

IF (CONDITION) IS TRUE
BEGIN
    UPDATE table SET columnx = 25
END
ELSE
BEGIN
    UPDATE table SET columny = 25
END

Sekarang ini memiliki keuntungan lain yaitu tidak ada penulisan yang tidak perlu pada tabel seperti solusi di atas.

Keras
sumber
ini adalah poin yang bagus dan alternatif yang bagus! Saya tidak lagi mengerjakan kode asli yang mengarah ke utas ini, tetapi selalu bagus untuk memiliki solusi yang berbeda dan saya pikir ini adalah solusi yang baik
pqsk
-1

Saya yakin Anda dapat menghilangkan pembaruan kolom "tidak diinginkan" dengan menyesuaikan jawaban lain sebagai berikut:
update table set columnx = (case when condition1 then 25 end), columny = (case when condition2 then 25 end)

Seperti yang saya pahami, ini akan diperbarui hanya jika kondisi terpenuhi.

Setelah membaca semua komentar, ini yang paling efisien:
Update table set ColumnX = 25 where Condition1 Update table set ColumnY = 25 where Condition1

Tabel Sampel:
CREATE TABLE [dbo].[tblTest]( [ColX] [int] NULL, [ColY] [int] NULL, [ColConditional] [bit] NULL, [id] [int] IDENTITY(1,1) NOT NULL ) ON [PRIMARY]
Data Sampel:
Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 0) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 0) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 1) Insert into tblTest (ColX, ColY, ColConditional) values (null, null, 1) Insert into tblTest (ColX, ColY, ColConditional) values (1, null, null) Insert into tblTest (ColX, ColY, ColConditional) values (2, null, null) Insert into tblTest (ColX, ColY, ColConditional) values (null, 1, null) Insert into tblTest (ColX, ColY, ColConditional) values (null, 2, null)

Sekarang saya berasumsi Anda dapat menulis kondisi yang menangani nulls. Untuk contoh saya, saya berasumsi bahwa Anda telah menulis kondisi yang bernilai True, False atau Null. Jika Anda membutuhkan bantuan dalam hal ini, beri tahu saya dan saya akan melakukan yang terbaik.

Sekarang menjalankan dua baris kode ini sebenarnya mengubah X menjadi 25 jika dan hanya jika ColConditional True (1) dan Y menjadi 25 jika dan hanya jika ColConditional False (0)

Update tblTest set ColX = 25 where ColConditional = 1 Update tblTest set ColY = 25 where ColConditional = 0

PS Kasus nol tidak pernah disebutkan dalam pertanyaan asli atau pembaruan apa pun pada pertanyaan, tetapi seperti yang Anda lihat, jawaban yang sangat sederhana ini tetap menangani mereka.

John Greiner
sumber
1
Ini sebenarnya tidak berhasil. Pertama, jika kolom memungkinkan null, maka ketika kondisi tidak terpenuhi, nilai null ditetapkan. Jika null tidak diizinkan, pembaruan akan gagal. Kueri "efisien" terakhir Anda adalah sql yang tidak valid, setidaknya di TSQL. Apakah Anda mengujinya pada mesin tertentu dan berhasil untuk Anda?
pqsk
Saya menguji ini di SQL Server 2005 dan berfungsi dengan sempurna seperti yang ditunjukkan. Saya yakin ingin tahu mengapa itu turun dipilih dan contoh yang menunjukkan nilai NULL diperbarui, karena dalam pengujian saya di atas, nilai null tidak diperbarui. Saya selalu berpikir bahwa jawaban paling sederhana adalah yang terbaik dan jika saya berurusan dengan database dengan jutaan catatan, saya yakin tidak ingin memperbarui baris yang tidak perlu.
John Greiner