Updating table using JOIN not working correctly - mysql

I'm doing something like this:
UPDATE `widget_list` a
JOIN `geography` b
ON b.`zip_code` = a.`zip_code`
SET b.`msa` = a.`msa`;
This executes just fine, but affects no rows. msa is set to NULL for all rows as if it wasn't changed at all. zip_code and msa are the same data types and length and definitely have overlapping zip_code. Any idea why this won't update?
EDIT: Update...I tried with a different column name and it ran as well, said that a set of my rows were affected, but none actually changed.
EDIT2: If I do this, then my msa column shows NULL for every row. Why wouldn't this value be here for a simple join?
SELECT * FROM `widget_list` a
JOIN `geography` b
ON b.`zip_code` = a.`zip_code`

Something like the below should work.
UPDATE `widget_list`
SET `msa` = (SELECT `msa` FROM `geography` b
JOIN `widget_list` a
ON `a`.`zip_code` = `b`.`zip_code`
);

Able to reproduce using this fiddle
However by changing the order on the set function it works... as in this fiddle
UPDATE `widget_list` a
JOIN `geography` b
ON b.`zip_code` = a.`zip_code`
SET a.`msa`=b.`msa` ;
and again that it should work.. implying it's a setup issue in your enviroment, or we're missing something (trigger perhaps?)
Working Fiddle Note however when mopre than one msa exists per zipcode A, X in my example for zip 123... the system simply picks one and uses it to update. X is lost in my example... are you sure that's not what's happening to you? (it's why I want to see sample data to see if it's a data issue vs syntax vs logic)
updated:
fiddle So if your source table has null values in the zipcodes you'll get null values in the destination table...
so what happens if we add....
UPDATE `widget_list` a
JOIN `geography` b
ON b.`zip_code` = a.`zip_code`
and b.msa is not null
SET a.`msa`=b.`msa` ;
and fiddle showing excluded nulls

Use from to do join.
UPDATE widget_list
SET b.msa = a.msa
FROM widget_list a JOIN geography b ON b.zip_code = a.zip_code

Related

MySQL - Update column value based on joined table column value

I've been reading through SO and other sites, and have followed a few examples; however, my SQL statments is still not performing as required.
I have two tables
parts
============================
pmkParts fnkManufacturer
----------------------------
0 Penn-Union
1 Schneider
2 Telemecanique
and
manufacturer
===============================
Manufacturer pmkManufacturer
-------------------------------
Penn-Union 45
Schneider 56
Telemecanique 12
I want to change the parts table into
parts
============================
pmkParts fnkManufacturer
----------------------------
0 45
1 56
2 12
Here is the SQL statement I tried.
Update parts
SET parts.fnkManufacturer = (
SELECT manufacturer.pmkManufacturer
FROM manufacturer
WHERE manufacturer.pmkManufacturer = parts.fnkManufacturer
)
That is changing the correct column, but it is filling it with 'NULLS' rather than the foreign key (manufacturer). I think there should be a join somewhere in there, but I'm not sure where.
Any tips?
----------
EDIT: Answer:
Here is the SQL statement that worked. Thanks MarcB for the help.
Update parts
SET parts.fnkManufacturer = (
SELECT manufacturer.pmkManufacturer
FROM manufacturer
WHERE manufacturer.Manufacturer= parts.fnkManufacturer
)
Try changing your query like below using a update join query. Again, you are joining on the wrong column, you actually should be joining to manufacturer.Manufacturer column rather.
Update parts p
JOIN manufacturer m ON m.Manufacturer = p.fnkManufacturer
SET p.fnkManufacturer = m.pmkManufacturer;
Your pmkManufacturer looks like int so it is better to add new int field to parts, update it and then remove old column. Something like this.
alter table dbo.parts add pmkManufacturer int
update dbo.parts
set pmkManufacturer = m.pmkManufacturer
from dbo.parts p
inner join dbo.Manufacturer m on p.fnkManufacturer = m.manufacturer
The best solution, you could use INNER JOIN, I for example :
update parts p
inner join manufacturer m on
p.pmkManufacturer = m.Manufacturer
set p.pmkManufacturer = m.pmkManufacturer
Howerver, in your case, if I was wrong, you want to update pmkManufacturer while pmkManufacturer is actually the condition ON for INNER JOIN so I'm not sure that it'okay for request. If not, it isn't also difficult, you could add a new column : pmk_bis_manufacturer and set the value into this column, then delete the old column pmkManufacturer and change the name of new column if nescessary.
One tip for you : the name of columns database, I prefer setting :
pmk_manufacturer instead of pmkManufacturer because capital letter in the name
could make one problem in the futur. For example : for ORM Doctrine,
it isn't good :D

MySQL Stored Procedure update using a Join and CASE..ELSE syntax

This is my first time creating a MySQL stored procedure and am stuck on getting the UPDATE piece to work correctly. The proc is performing an inner join, looking for matches on a domain name field. If there is a match, a column named inbound is getting updated with a value of 0. If there is not a match on the join, then I need inbound set to a value of 1.
When I run this, I am able to get the matches tagged with a 0, but the non-matches are not getting updated with a 1. I thought how I have the 'ELSE' part set up would take care of this- can anyone tell if I am missing something with the syntax?
CREATE PROCEDURE `sp_InboungTagging`()
BEGIN
update `tableA` a
inner join `TableD` d
on a.senderDomain = d.domainName
set inbound = CASE
when a.senderDomain = d.domainName then 0
ELSE 1
END
WHERE inbound is null;
END;|
DELIMITER ;
Thanks,
Ron
EDIT-
Thanks for your reply. I am looking for exact matches on a varchar field that has domain names in it- the master list of domains is in table D. If the record in TableA has a match in TableD, I want to tag that recored with a 0. If there is no match in TableD, then I would like to tag it with a 1. Let me know if that clears things up- thanks
Your JOIN condition is the same as your CASE condition. If you JOIN your two tables on:
a.senderDomain = d.domainName
Then there will be no values in the result set for which
a.senderDomain != d.domainName
so the ELSE clause of your CASE statement never fires.
Without knowing more about what you mean by "matches" and "non-matches," I can't really suggest a correction.

Copying One column from table to another table that has matching variables in another column

I hope I can explain this to make sense lol.
I am trying to copy variables from one hats_old.red to hats_new.red that match hats_new.name in both tables, if they do not match then i need it to do nothing so it does not null the value or set it to 0.
This is as far as ive gotten. This changes unmatched to 0 which i am trying to avoid and cannot figure the rest out.
This is for Mysql
Thank you
UPDATE hats_new
SET hats_new.red = (
SELECT hats_old.red
FROM hats_old
WHERE hats_old.name = hats_new.name LIMIT 1
);
An update with a join should do the trick:
UPDATE hats_new hn
JOIN hats_old ho ON hn.name = oh.name
SET hn.red = ho.red

How to copy 3 columns from one table into another in mysql

I have two tables and both include 2 columns, sureness and kindness and and they are related to each other by dataitemID and id. Just to show you the structure I will put 2 selects that I got from database:
SELECT ID,sureness,kindness FROM omid.tweet ;
SELECT ID,DataitemID,sureness,kindness FROM omid.entity_epoch_data ;
and I want to copy all value of sureness and kindness in omid.tweet into entity_epoch_data where entity_epoch_data.entityID is equal to entityID coming from entity_relation where tweet.ID =entity_relation.ID
I want just to do it in mysql rather than reading the whole table in java and updating the database in the loop but I am so confused. How can I do that?I appreciate any help:)
Update:
I wrote the code as follow but it does not work:
update tweet, entity_epoch_data
set entity_epoch_data.sureness= tweet.sureness,
entity_epoch_data.kindness = tweet.kindness ,
entity_epoch_data.calmness = tweet.calmness ,
entity_epoch_data.happiness = tweet.happiness
WHERE entity_epoch_data.EntityID in(
SELECT EntityID FROM omid.entity_dataitem_relation
INNER JOIN omid.tweet t ON entity_dataitem_relation.DataitemID = t.ID)
It's actually pretty straight forward. The UPDATE clause works like a JOIN and then use SET to set the values
UPDATE tweet INNER JOIN entity_epoch_data
ON tweet.id = entity_epoch_data.id
SET entity_epoch_data.sureness= tweet.sureness,
entity_epoch_data.kindness = tweet.kindness

How to set a column value equal to the value in another table?

I am trying to figure out how to update a row in one table, setting a column value equal to a value in a different table. Here's an example:
movies:
movie_id | movie_price
movies_attended:
attended_id | attended_movie_id | attended_movie_price
Now, this is kind of a stupid example, but supposed that for some reason there is a row in movies_attended that does not have the correct attended_movies_price in it and so it needs to be updated.
How should a query be written to update the movies_attended table, setting movies_attended.attended_movie_price = movies.movie_price?
I tried something similar to the following, but it did not work:
update movies_attended, movies
set movies_attended.attended_movie_price = movies.movie_price
where movies_attended.attended_movie_id = movies.movie_id
AND attended_id = [the id of the row we want to update]
When you say "it did not work", do you mean that it reported 0 rows updated, or did the statement cause the database raise an exception?
Your example statement appears to be of the form:
UPDATE movies_attended a
JOIN movies m
ON a.attended_movie_id = m.movie_id
SET a.attended_movie_price = m.movie_price
WHERE a.attended_id = ?
(We typically prefer the JOIN ... ON ... style syntax to the comma join operator and the join predicates in the WHERE clause.)
I have no explanation as to why this statement would "not work".
It's possible this would report 0 rows affected, if no rows satisfy the predicates. It would also report 0 rows affected if the rows that would be changed do not require any changes... that is, the existing value in attended_movie_price already matches the value being assigned to it.
Normally, before running an update statement like that, I write it as a SELECT first, and see what values are returned...
By replacing the UPDATE keyword with SELECT ... FROM, and removing the SET clause:
SELECT m.movie_price AS new_val
, a.attended_movie_price AS old_val
, a.attended_id
FROM UPDATE movies_attended a
JOIN movies m
ON a.attended_movie_id = m.movie_id
WHERE a.attended_id = ?
This is actually a bad database design. You don't need movie price in two tables.
But, if you just need this, it goes something along this:
UPDATE movies_attended
INNER JOIN
movies
ON movies_attended.attended_movie_id = movies.movie_id
SET movies_attended.attended_movie_price = movie.movie_price