views:

47

answers:

1

Hi,
I use a MySQL DB, and I would like to update a field in a table based on another. Something like:

UPDATE table1
SET field1 = table2.id
WHERE field2 IN (
    SELECT table2.name
    FROM table2
    );

I know that this query wouldn't work, but here is the idea. Is that even possible to do?

Cheers,
Nicolas.

A: 

You can use a correlated sub query as below. This assumes there will be exactly one matching value returned. It will raise an error if more than one matching value is returned or set the field to null if zero are returned. If that last behaviour isn't desirable you will need a where clause.

UPDATE table1
SET field1 = (SELECT DISTINCT table2.ValueColumn 
              FROM table2 
              WHERE table2.JoinColumn = table1.JoinColumn)

Edit

To review records with 0 or more than 1 matches you could use

SELECT table1.JoinColumn, COUNT(DISTINCT table2.ValueColumn)
FROM table1 
LEFT JOIN table2
ON table2.JoinColumn = table1.JoinColumn
GROUP BY table1.JoinColumn
HAVING COUNT(DISTINCT table2.ValueColumn) <> 1
Martin Smith
Yeah You're right, thanks. I didn't think about that possibility.
Nicolas
@Nicolas There's probably a JOIN syntax for this as well. There is in SQL Server but I'm not sure it's the same in MySQL
Martin Smith
@Martin I'm currently testing it and I can't get rid of this error: `Subquery returns more than 1 row` despite trying adding DISTINCT in the subquery.
Nicolas
For some values there must be more than 1 possible results in your other table then. How do you want to handle those?
Martin Smith
@Martin: Yeah that's what the ouput is saying, but I tried a count() on the column name, and there isn't any value more than once. Really strange I can't see how it can returns more than one value in this case
Nicolas
@Nicolas What is returned by the query in my edit?
Martin Smith
@Martin: `MySQL returned an empty result set (i.e. zero rows). ( Query took 0.1746 sec )`
Nicolas
@Nicolas Is table2.ValueColumn `NULL` for any values?
Martin Smith
@Martin: Nope. Strangely, the select returns values:`SELECT * FROM table1 u WHERE u.location = ( SELECT distinct c.id FROM table2 c WHERE lower(c.name) = lower(u.outside_location) )`
Nicolas
I'm out of ideas then!
Martin Smith
Ok, I'll keep this question updated as soon as I find the answer (if so). Cheers anyway :)
Nicolas
@Nicolas You could use an aggregate to ensure only one value can be returned by the sub query but I'm extremely hesitant to suggest that as it could just mask some problem that you haven't yet spotted.
Martin Smith
@Martin: My bad; actually it worked, but I can't remember seeing any output about this, and if I still try the UPDATE it fails. Anyway, thank you for the help.
Nicolas