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 4

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, соответственно:

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";
Хорошо, подведем итог, вот весь процесс, который я использовал, чтобы получить желаемые результаты в MainTable (как указано в опубликованном вопросе):
  1. создать GoodTable вид
  2. Create BadTable вид
  3. Create MatchTable вид
  4. выполнить обновить запрос на обновление MainTable
  5. празднуйте дико! (Просто шучу - я не могу избавиться от ноющего чувства, что должен быть лучший/более эффективный способ сделать это!) Но серьезно, празднуйте дико !

(еще раз спасибо @DBug за то, что вывел меня на правильный путь для обновления части и @Rabbit за то, что привел меня к таблице матчей!)