T-SQL: Sử dụng CASE trong câu lệnh UPDATE để cập nhật các cột nhất định tùy thuộc vào điều kiện


108

Tôi đang tự hỏi nếu điều này là có thể ở tất cả. Tôi muốn cập nhật cột x nếu một điều kiện là đúng, nếu không cột y sẽ được cập nhật

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

Tôi đã tìm kiếm khắp nơi, thử một số thứ và không thể tìm ra giải pháp. Tôi nghĩ là không được, nhưng tôi nghĩ tôi sẽ hỏi ở đây và xem có ai đã làm điều đó trước đây chưa. Cảm ơn trước.


Giả sử tất cả trong cùng một bảng, có. Bạn luôn có thể chạy nó trong một giao dịch và khôi phục lại lỗi, hãy tự mình kiểm tra.
OMG Ponies

Tôi không chắc bạn muốn nói gì. Tôi đã thử đặt một điều kiện cho cột, nhưng nó không hoạt động. Nó hoạt động với câu lệnh select, nhưng không hoạt động với câu lệnh cập nhật. (Select (case (điều kiện) khi true rồi đến cộtx else columny end) từ myTable .... bản cập nhật không hoạt động và tôi có thể hiểu tại sao. Không có ' t dường như một cách để làm cho rằng công việc.
pqsk

Câu trả lời:


188

Bạn không thể sử dụng một điều kiện để thay đổi cấu trúc truy vấn của mình, chỉ dữ liệu liên quan. Bạn có thể làm điều này:

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

Điều này giống nhau về mặt ngữ nghĩa, nhưng chỉ cần lưu ý rằng cả hai cột sẽ luôn được cập nhật . Điều này có thể sẽ không gây ra bất kỳ vấn đề nào cho bạn, nhưng nếu bạn có khối lượng giao dịch cao, thì điều này có thể gây ra các vấn đề đồng thời.

Cách duy nhất để thực hiện cụ thể những gì bạn đang yêu cầu là sử dụng SQL động. Tuy nhiên, đây là điều mà tôi khuyến khích bạn nên tránh xa. Giải pháp trên gần như chắc chắn sẽ đủ cho những gì bạn đang theo đuổi.


Tôi đồng ý về SQL động. Vậy dữ liệu của tôi có bị ảnh hưởng không? Ý tôi là tôi không muốn nó bị thay đổi vì điều kiện nhất định. Vì vậy, nó sẽ chỉ chèn lại những gì đã có trong đó? Lượng truy cập vào db có thể không quá tệ.
pqsk

@pqsk: Điều này sẽ không ảnh hưởng đến dữ liệu của bạn, nó chỉ nên chèn lại những gì đã có cho bất kỳ cột nào được cho là không bị ảnh hưởng.
Adam Robinson

Cảm ơn. Tôi sẽ đi với điều này. Thật đơn giản, ngay cả một thượng cổ cũng có thể làm được. haha.
pqsk

1
@AdamRobinson 1,5 năm được thông qua bạn có biết một số cách hiệu quả hơn để cập nhật chỉ có một cột

@Somebodyisintrouble: Cách duy nhất để cập nhật một cột là sử dụng một truy vấn khác.
Adam Robinson

23
UPDATE  table
SET     columnx = CASE WHEN condition THEN 25 ELSE columnx END,
        columny = CASE WHEN condition THEN columny ELSE 25 END

1
Bạn vừa sao chép câu trả lời của Adam, hay câu trả lời này được lấy từ một nơi khác? haha. Chỉ cần nhận thấy rằng.
pqsk

1
@pqsk: phản ứng của chúng tôi là ~ 1 phút ngoài, vì vậy tôi muốn tưởng tượng tôi chỉ nhấp nộp một chút nhanh hơn;)
Adam Robinson

23
@pqsk: vâng, tôi vừa sao chép câu trả lời của Adam, 23vài giây trước khi anh ấy đăng nó. Tôi là một copypaster nhanh!
Quassnoi

2
@pqsk: nếu bạn đặt con trỏ qua * min ago, nó sẽ hiển thị cho bạn thời gian chính xác nó được đăng.
Quassnoi

2
Công bằng mà nói, mặc dù cả hai đều giống nhau: nếu Adam sẽ xuất hiện sau bạn, anh ấy đã giải thích thêm một số chi tiết. Đó là lý do tại sao tôi đánh dấu anh ấy là câu trả lời. Xin cảm ơn.
pqsk

4

nhập mô tả hình ảnh ở đây

Tôi muốn thay đổi hoặc cập nhật ContactNo của mình thành 8018070999 trong đó có 8018070777 bằng cách sử dụng câu lệnh Case

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

nhập mô tả hình ảnh ở đây


1
cho điều này tại sao không sử dụng CẬP NHẬT truy vấn này [Liên hệ] SET contactNo = 8018070999 Ở ĐÂU contactNo = 8018070777
NewGuy

4

Tôi biết đây là một câu hỏi rất cũ, nhưng điều này đã hiệu quả với tôi:

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

Trân trọng


1

Tôi biết đây là một câu hỏi rất cũ và sự cố được đánh dấu là đã khắc phục. Tuy nhiên, nếu ai đó có trường hợp như tôi, trong đó bảng có kích hoạt ghi dữ liệu về các sự kiện cập nhật, điều này sẽ gây ra vấn đề. Cả hai cột sẽ nhận được cập nhật và nhật ký sẽ làm cho các mục nhập vô ích. Cách tôi đã làm

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

Bây giờ điều này có một lợi ích khác là nó không có các ghi không cần thiết trên bàn như các giải pháp trên.


đây là một điểm tốt và thay thế tốt! Tôi không còn làm việc với mã gốc dẫn đến chủ đề này nữa, nhưng tôi luôn tốt khi có các giải pháp khác nhau và tôi nghĩ đây là một giải pháp tốt
pqsk 11/02/19

-1

Tôi tin rằng bạn có thể bỏ qua việc cập nhật các cột "không mong muốn" bằng cách điều chỉnh các câu trả lời khác như sau:
update table set columnx = (case when condition1 then 25 end), columny = (case when condition2 then 25 end)

Theo tôi hiểu, điều này sẽ chỉ cập nhật khi điều kiện được đáp ứng.

Sau khi đọc tất cả các bình luận, đây là cách hiệu quả nhất:
Update table set ColumnX = 25 where Condition1 Update table set ColumnY = 25 where Condition1

Bảng mẫu:
CREATE TABLE [dbo].[tblTest]( [ColX] [int] NULL, [ColY] [int] NULL, [ColConditional] [bit] NULL, [id] [int] IDENTITY(1,1) NOT NULL ) ON [PRIMARY]
Dữ liệu mẫu:
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)

Bây giờ tôi giả sử bạn có thể viết một điều kiện xử lý các giá trị rỗng. Đối với ví dụ của tôi, tôi giả sử bạn đã viết một điều kiện như vậy để đánh giá là True, False hoặc Null. Nếu bạn cần trợ giúp về vấn đề này, hãy cho tôi biết và tôi sẽ cố gắng hết sức.

Bây giờ chạy hai dòng mã này, infact sẽ thay đổi X thành 25 nếu và chỉ khi Điều kiện màu là Đúng (1) và Y thành 25 nếu và chỉ khi Điều kiện màu là Sai (0)

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

PS Trường hợp rỗng không bao giờ được đề cập trong câu hỏi ban đầu hoặc bất kỳ cập nhật nào cho câu hỏi, nhưng như bạn có thể thấy, câu trả lời rất đơn giản này vẫn xử lý chúng.


1
Điều này thực sự không hoạt động. Đối với một, nếu cột cho phép giá trị rỗng, thì khi điều kiện không được đáp ứng, giá trị null sẽ được gán. Trong trường hợp không cho phép null thì quá trình cập nhật sẽ không thành công. Truy vấn "hiệu quả" cuối cùng của bạn là sql không hợp lệ, ít nhất là trong TSQL. Bạn đã thử nghiệm điều này trên một công cụ cụ thể và nó có hiệu quả với bạn không?
pqsk

Tôi đã thử nghiệm điều này trên SQL Server 2005 và nó hoạt động hoàn hảo như được hiển thị. Tôi chắc chắn muốn biết lý do tại sao nó bị bỏ phiếu và một ví dụ hiển thị giá trị NULL đang được cập nhật, bởi vì trong thử nghiệm của tôi ở trên, giá trị null không được cập nhật. Tôi luôn nghĩ rằng câu trả lời đơn giản nhất là tốt nhất và nếu tôi đang xử lý một cơ sở dữ liệu với hàng triệu bản ghi, tôi chắc chắn không muốn cập nhật các hàng không cần thiết.
John Greiner
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.