#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');
Как уже упоминалось, это, очевидно, намного проще с нормализованным дизайном