T-SQL: Використання CASE в операторі UPDATE для оновлення певних стовпців залежно від умови


108

Мені цікаво, чи це взагалі можливо. Я хочу оновити стовпець x, якщо умова є правдою, інакше стовпець y буде оновлений

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

Я шукав всюди, спробував деякі речі і не можу знайти рішення. Я думаю, що це неможливо, але я подумав, що запитаю тут і побачу, чи хтось робив це раніше. Заздалегідь спасибі.


Якщо припустити, що всі в одній таблиці, так. Ви завжди можете запустити його в операції та відкатати помилково, щоб переконатися в цьому.
OMG Ponies

Я не впевнений, що ти маєш на увазі. Я спробував поставити умовний для стовпця, але це не працює. Він працює для оператора select, але не для оператора оновлення. (Виберіть (випадок (умова), коли істинний, тоді стовпчикx інакше стовпчиковий кінець) з myTable .... оновлення не працює, і я можу зрозуміти, чому. t, здається, спосіб зробити цю роботу.
pqsk,

Відповіді:


188

Ви не можете використовувати умову, щоб змінити структуру вашого запиту, лише задіяні дані. Ви можете зробити це:

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

Це семантично те саме, але слід пам’ятати, що обидва стовпці завжди будуть оновлюватися . Це, ймовірно , не викличе у вас жодних проблем, але якщо у вас великий обсяг транзакцій, це може спричинити проблеми одночасності.

Єдиний спосіб зробити конкретно те, що ви просите, - це використовувати динамічний SQL. Це, однак, я б заохочував вас триматися подалі. Наведеного рішення майже напевно буде достатньо для того, що ви хочете.


Я згоден щодо динамічного SQL. Тож чи вплинуть мої дані? Я маю на увазі, я не хочу, щоб це змінилося для певного стану. Тож це буде просто знову вставити те, що вже є там? Кількість звернень до db може бути не дуже поганою.
pqsk

@pqsk: Це не повинно впливати на ваші дані, воно повинно просто вставити те, що вже є, для того, який колонка не повинна впливати.
Адам Робінсон

Дякую. Я збираюся йти з цим. Так просто, навіть печерний чоловік може це зробити. ха-ха.
pqsk

1
@AdamRobinson минуло 1,5 року. Чи знаєте ви якийсь більш ефективний спосіб оновити лише одну колонку

@Somebodyisintrouble: Єдиний спосіб оновити один стовпець - це використовувати інший запит.
Адам Робінсон

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

1
Ви просто скопіювали відповідь Адама, або це було взято з іншого місця? ха-ха. Щойно це помітив.
pqsk

1
@pqsk: Наші відповіді були за 1 хвилину один від одного, тому я думаю, що я просто натиснув подати трохи швидше;)
Адам Робінсон

23
@pqsk: так, я просто скопіював відповідь Адама, 23секунди до того, як він його опублікував. Я один швидкий копіпастер!
Quassnoi

2
@pqsk: якщо ви помістите курсор на * min ago, він покаже точний час його публікації.
Quassnoi

2
Якщо бути справедливим, навіть якщо обидва однакові: якби Адам вийшов би за вашим, він ще трохи розробив. Тому я позначив його як відповідь. Спасибі, хоча.
pqsk

4

введіть тут опис зображення

Я хочу змінити або оновити своє ContactNo на 8018070999, де є 8018070777 за допомогою оператора Case

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

введіть тут опис зображення


1
для цього, чому б не використати цей запит ОНОВЛЕННЯ [Контакти] Встановити контактNo = 8018070999 ДЕ contactNo = 8018070777
NewGuy


1

Я знаю, що це дуже давнє питання, і проблема позначена як виправлена. Однак якщо хтось із таким випадком, як у мене, де у таблиці є тригер для реєстрації даних про події оновлення, це спричинить проблеми. Обидва стовпці отримають оновлення, а журнал зробить марні записи. Як я і зробив

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

Тепер це має ще одну перевагу, що у нього немає зайвих записів на стіл, як описані вище рішення.


це хороший момент і хороша альтернатива! Я більше не працюю з оригінальним кодом, який веде до цієї теми, але завжди добре мати різні рішення, і я думаю, що це хороше рішення
pqsk

-1

Я вважаю, що ви можете опустити оновлення стовпців "небажаних", скоригувавши інші відповіді так:
update table set columnx = (case when condition1 then 25 end), columny = (case when condition2 then 25 end)

Як я розумію, це оновиться лише тоді, коли умова буде виконана.

Прочитавши всі коментарі, це найефективніше:
Update table set ColumnX = 25 where Condition1 Update table set ColumnY = 25 where Condition1

Прикладна таблиця:
CREATE TABLE [dbo].[tblTest]( [ColX] [int] NULL, [ColY] [int] NULL, [ColConditional] [bit] NULL, [id] [int] IDENTITY(1,1) NOT NULL ) ON [PRIMARY]
вибіркові дані:
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)

тепер я припускаю, що ви можете написати умовний, що обробляє нулі. Для мого прикладу, я припускаю, що ви написали такий умовний варіант, який оцінює значення True, False або Null. Якщо вам потрібна допомога в цьому, дайте мені знати, і я зроблю все можливе.

Тепер запуск цих двох рядків коду недійсний змінює X на 25, якщо і тільки якщо ColConditional є True (1) і Y до 25, якщо і тільки якщо ColConditional є False (0)

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

PS Нульовий випадок ніколи не згадувався в оригінальному запитанні чи будь-яких оновленнях питання, але, як ви бачите, ця дуже проста відповідь все одно справляється з ними.


1
Це насправді не працює. Для одного, якщо стовпець допускає нулі, тоді, коли умова не виконується, призначається нульове значення. У випадку, коли нулі заборонені, оновлення не вдасться. Ваш остаточний "ефективний" запит недійсний sql, принаймні в TSQL. Ви тестували це на певному двигуні, і він працював на вас?
pqsk

Я тестував це на SQL Server 2005, і він відмінно працює, як показано. Я би хотів би знати, чому це було проголосовано, і приклад показує, що значення NULL оновлюється, оскільки в моєму тесті вище нульове значення не оновлюється. Я завжди вважав, що найпростіша відповідь найкраща, і якщо я маю справу з базою даних з мільйонами записів, я впевнений, що не хочу оновлювати непотрібні рядки.
Джон Грейнер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.