Mysql: update query with subquery
The question is a unclear on how the tables are to actually related to each other.

Since the query you've posted is not working, it's difficult to tell which element of the logic contains the error, and with a column called "oldID" it's hard to understand the necessary join logic.

I have attempted to interpret and rewrite your query based on trying to understand it from the innermost query to the outermost query, it seems like this might be what you are trying to accomplish.

My table "ta" is doing the same thing as your table "ta" seems to be trying to do, and my table "a" is doing the same thing your table "a" seems to be trying to do.  They are reversed in their order of appearance in the query because, as I mentioned, if I'm understanding your query correctly, the original query seems to be written inside-out.

UPDATE Taxonomy t
  JOIN TaxonomyMapping ta ON ta.oldID = t.oldID
  JOIN CategoryMapping cm ON cm.language_ID = ta.oldID
  JOIN TaxonomyMapping a ON a.oldID = cm.en_id
   SET t.sourceId = a.id
 WHERE t.id &gt; -1;


However, if your "TaxonomyMapping" and "Taxonomy" tables are an "exact copy" (containing the same data) then table "ta" is not necessary, and all you actually need is this:

UPDATE Taxonomy t
  JOIN CategoryMapping cm ON cm.language_ID = t.oldID
  JOIN TaxonomyMapping a ON a.oldID = cm.en_id
   SET t.sourceId = a.id
 WHERE t.id &gt; -1;


In fact, it seems like you could even do it without a permanent copy.

UPDATE Taxonomy t
  JOIN CategoryMapping cm ON cm.language_ID = t.oldID
  JOIN (SELECT * FROM Taxonomy) x ON x.oldID = cm.en_ID
   SET t.sourceId = x.id
 WHERE t.id &gt; -1;


That last example works because the server materializes a temporary copy of "Taxonomy" called table "x" before executing the rest of the query.  By doing that, it's able to update the table with data selected from elsewhere in the same table, which you normally can't do... but since a copy is technically a different table, it works.  The temporary copy is usually created in memory and then moved to disk if it turns out to be large, but either way, it's automatically deleted as soon as the query is finished.  The down-side is that the new table won't have any indexes so this approach won't infinitely scale... but should still be faster than your original correlated subquery.

Of course, none of these will work if I have failed to understand the necessary logic.