Обновите разные строки с одинаковым идентификатором, если одна строка равна чему-то

#sql #sql-server

Вопрос:

Я должен проверить поле «если COUNTRY = 'England' «, если да , то мне нужно обновить FIELD_VALUE для FIELD_NAME CITY того , чтобы 'London' , FIRST_NAME чтобы 'John' , LAST_NAME чтобы 'Doe' для того же идентификатора, который есть в этой СТРАНЕ.

ID ИМЯ ПОЛЯ ЗНАЧЕНИЕ ПОЛЯ
10 Страна Англия
10 город ТемпСити
10 ИМЯ ПОЛЬЗОВАТЕЛЯ Временное имя
10 ФАМИЛИЯ ТемпЛаст

Каков был бы лучший способ сделать это? У меня около 1000 идентификаторов с разными FIELD_VALUE именами FIELD_NAME = COUNTRY .

Я работаю над чужой базой данных и не могу изменить дизайн этой таблицы.

Комментарии:

1. Это было бы значительно проще при нормализованном дизайне. Если вы пошли по пути подслушивания, то вам лучше внести такие изменения в приложение, которые вынудили вас отказаться от денормализованного дизайна.

2. Эта модель в СУБД вызывает пару Ключ/значение, как вспашка поля велосипедом вместо плоттера. Используйте соответствующий дизайн или используйте соответствующие СУБД !

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

Ответ №1:

Вы могли бы использовать:

 UPDATE yourTable SET CITY = 'London', FIRST_NAME = 'John', LAST_NAME = 'Doe' WHERE ID IN (SELECT ID FROM yourTable WHERE COUNTRY = 'England');  

Но, как уже упоминалось в комментариях, более нормализованный дизайн может быть намного проще в использовании.

Ответ №2:

С использованием только обновления:

 UPDATE T  SET FIELD_VALUE = CASE   WHEN T.FIELD_NAME = 'CITY' THEN 'London'  WHEN T.FIELD_NAME = 'FIRST_NAME' THEN 'John'  WHEN T.FIELD_NAME = 'LAST_NAME' THEN 'Doe'  ELSE T.FIELD_VALUE  END FROM T  INNER JOIN T AS T1 ON (T.ID = T1.ID) WHERE T1.FIELD_NAME = 'COUNTRY'   AND T1.FIELD_VALUE = 'England'   AND T.FIELD_NAME IN ('CITY', 'FIRST_NAME', 'LAST_NAME')  

Ответ №3:

Вы можете использовать обновляемый CTE

 WITH cte AS (  SELECT *,  IsCtryEngl = COUNT(CASE WHEN FIELD_NAME = 'COUNTRY' AND FIELD_VALUE = 'England' THEN 1 END)  OVER (PARTITION BY ID)  FROM YourTable  WHERE FIELD_NAME IN ('COUNTRY', 'FIRST_NAME', 'LAST_NAME', 'CITY') ) UPDATE cte SET  FIELD_VALUE = CASE FIELD_NAME  WHEN 'FIRST_NAME' THEN 'John'  WHEN 'LAST_NAME' THEN 'Doe'  WHEN 'CITY' THEN 'London'  END WHERE IsCtryEngl gt; 0  AND FIELD_NAME IN ('FIRST_NAME', 'LAST_NAME', 'CITY');  

Как уже упоминалось, это, очевидно, намного проще с нормализованным дизайном