SQL для обновления выбранных полей в таблице из представления
Я новичок в этом, поэтому заранее приношу извинения за любую путаницу/разочарование. Я ценю любую помощь, которую могу получить!
У меня есть таблица ( MainTable), в которой я создал два представления ( GoodTable и BadTable).
- каждая таблица имеет 4 столбца (ID, UserID, ключ, значение ).
- ID является первичным ключом, но
- UserID может повторяться в несколько строк.
Что мне нужно сделать в Главная таблица-это найти ID s, которые находятся в плохой таблице, и обновить значения из столбца value таблицы GOOD , основываясь на совпадении UserID и аналогичное совпадение с ключевым столбцом, в главную таблицу.
Я надеюсь, что это имеет смысл.Я пробовал:
UPDATE MainTable
SET value = (SELECT value FROM GoodTable
WHERE MainTable.UserID = GoodTable.UserID
AND MainTable.key LIKE "some%key%specifics");
Это приводит меня почти туда, но проблема в том, что если он не находит подобных ключевых особенностей, он возвращает нулевое значение и я хотите, чтобы он сохранил свое исходное значение, если оно не находится в BadTable (BadTable-это, по сути, все ключи, соответствующие подобным ключевым особенностям). Очевидно, что выше не используется BadTable, но я подумал, что это может помочь мне решить эту проблему (не тот случай, пока!)...
Вот небольшой пример:
MainTable:
ID UserID key value
1 1 key1 good value
2 1 key2 bad value
3 1 key3 unrelated value
4 2 key1 good value
5 2 key2 bad value
6 2 key3 unrelated value
GoodTable:
ID UserID key value
1 1 key1 good value
4 2 key1 good value
BadTable:
ID UserID key value
2 1 key2 bad value
5 2 key2 bad value
What I want MainTable to change to:
ID UserID key value
1 1 key1 good value
2 1 key2 good value
3 1 key3 unrelated value
4 2 key1 good value
5 2 key2 good value
6 2 key3 unrelated value
Я также подумал, что если бы было что-то вроде VLOOKUP (например, в Excel), где я мог бы сказать, что делать, если ложь, но я не был в состоянии решить это тоже. Я уже пробовал кое - что другое. исследуя другие вопросы, но у меня закружилась голова, и я решил обратиться за помощью:)
Наконец, я не уверен, имеет ли это значение или нет, но это если для MySQL...
Я уверен, что делаю это более сложным для себя, чем мне нужно, поэтому я действительно ценю любую помощь, которую кто-либо может предоставить!
UPDATE : в соответствии с предложением @Rabbit, это лучшее, что я мог придумать, используя внутреннее соединение (хотя я думал, что это добавит к MainTable, но я хочу сохранить количество строк в MainTable то же самое, просто обновите это одно поле для соответствующих строк..):
UPDATE MainTable
JOIN GoodTable ON MainTable.ID = GoodTable.ID
SET value = (SELECT value FROM GoodTable
WHERE MainTable.UserID = GoodTable.UserID
AND MainTable.key LIKE "some%key%specifics");
Я уверен, что это ужасная попытка, но я, безусловно, новичок здесь!
Мне удалось найти решение (хотя я уверен, что оно крайне неэффективно) - пожалуйста, смотрите ответ ниже! (Спасибо @DBug и @Rabbit за то, что указали мне правильное направление!)
4 ответа:
Вы сказали "главная таблица-найти идентификаторы, которые находятся в плохой таблице, и обновить значения из столбца value хорошей таблицы, основываясь на совпадении UserID и аналогичном совпадении с ключевым столбцом, в главную таблицу. " Итак, ваш результат выборки неверен...
Мы обновим 2 и 5 ID из MainTable правильно? ведь именно в BadTable , но 2 и 5 ключ 2 ключа и нет никакого ключа 2 на GoodTable.
Если я буду основываться на вашем ответе. Это может помочь ты. Пожалуйста, проверьтеUPDATE MainTable m INNER JOIN BadTable b ON m.id = b.id LEFT JOIN GoodTable g ON b.UserID = g.UserID SET m.value = g.value
Немного исправим это. для ключа , который вы хотели
Можно использовать функцию Coalesce, которая возвращает первый ненулевой аргумент, давая ему столбец value из обеих таблиц, например
UPDATE MainTable SET value = (SELECT COALESCE(GoodTable.value, MainTable.value) FROM GoodTable WHERE MainTable.UserID = GoodTable.UserID AND MainTable.key LIKE "some%key%specifics");
Он вернет GoodTable.значение, если оно не равно NULL или MainTable.ценность, если она есть.
Нет необходимости использовать подзапрос, вы можете использовать соединение в предложении UPDATE.
UPDATE Table1 INNER JOIN Table2 ON Table1.FieldName = Table2.FieldName SET .... WHERE ....
Это в конечном итоге сработало для меня, но обратите внимание, что мне нужно было создать еще один вид (MatchTable):
UPDATE MainTable SET value = COALESCE((SELECT value FROM MatchTable WHERE MainTable.ID = MatchTable.ID AND MainTable.key LIKE "some%key%specifics"),(SELECT value));
MatchTable по существу берет плохие строки (из BadTable) и обновляет их значение с хорошими значениями из GoodTable. Вот код, который я использовал для этого:
CREATE VIEW MatchTable AS SELECT (BadTable.ID) AS "ID", (BadTable.UserID) AS "UserID", (BadTable.key) AS "key", (SELECT value FROM GoodTable WHERE BadTable.UserID = GoodTable.UserID) AS "value" FROM BadTable LEFT JOIN GoodTable ON GoodTable.ID = BadTable.ID;
Это привело к следующим данным в MatchTable:
MainTable: ID UserID key value 2 1 key2 good value 5 2 key2 good value
Для полноты решения, и если это случится, чтобы помочь кому-то еще, здесь это запросы, которые я использовал для создания GoodTable и BadTable, соответственно:
Хорошо, подведем итог, вот весь процесс, который я использовал, чтобы получить желаемые результаты в MainTable (как указано в опубликованном вопросе):CREATE VIEW GoodTable AS SELECT * FROM MainTable WHERE key = "specific_key_term"; CREATE VIEW BadTable AS SELECT * FROM MainTable WHERE key LIKE "some%key%specifics";
- создать GoodTable вид
- Create BadTable вид
- Create MatchTable вид
- выполнить обновить запрос на обновление MainTable
- празднуйте дико! (Просто шучу - я не могу избавиться от ноющего чувства, что должен быть лучший/более эффективный способ сделать это!) Но серьезно, празднуйте дико !
(еще раз спасибо @DBug за то, что вывел меня на правильный путь для обновления части и @Rabbit за то, что привел меня к таблице матчей!)