I've tried lots of versions of this update query using answers from previous questions but can't seem to get it to work. The latest one I have returns 0 rows affected.
I get 2017 results when I run this query (which is what I want)
SELECT *
FROM table_1 t1
INNER JOIN table_2 t2 ON t1.company = t2.company
WHERE t1.user = 123 AND t2.group_id = 3
But I want to run an update query like this
UPDATE table_1 AS t1
INNER JOIN table_2 as t2
ON t1.company = t2.company
SET t1.user = t2.user
WHERE t1.user = 123 AND t2.group_id = 3
But I get 0 rows affected
Why does this update query not update the 2017 records that are returned in query 1?
I expect your select query is returning too many rows, as you have an error:
INNER JOIN table_2 t2 ON t2.company = t2.company
I think you want:
INNER JOIN table_2 t2 ON t1.company = t2.company
Are you sure that the table_1.user and table_2.user values are actually different before you run the update query? MySQL will report the number of rows that were actually changed, not the number of rows that were selected and examined.
Try running this query first, to see how many of your 2017 rows actually need updating:
SELECT *
FROM table_1 t1
INNER JOIN table_2 t2 ON t1.company = t2.company
WHERE t1.user = 123 AND t2.group_id = 3
AND t1.user <> t2.user
Update
It turns out that this can happen if the data types are similar enough to be compared, but not enough that the values in table_2.user can be assigned to table_1.user. In that case, MySQL will issue a warning ("Out of range value adjusted for column 'user' at row xxx"), but will otherwise allow the query to succeed. Running the query again will show that the values are still different, but won't change what is actually stored in t1.user.
If you modify the update query to only match the rows that need to be changed, and run this from the command line, then MySQL will tell you exactly what's going on:
mysql> UPDATE table_1 AS t1
-> INNER JOIN table_2 as t2
-> ON t1.company = t2.company
-> SET t1.user = t2.user
-> WHERE t1.user = 123 AND t2.group_id = 3
-> AND t1.user <> t2.user
Query OK, 0 rows affected, 2017 warnings (0.01 sec)
Rows matched: 2017 Changed: 0 Warnings: 2017
Rows matched: 2017 indicates that there were 2017 rows that need to be updated (if the values were already correct, this would be 0)
Changed: 0 means that none of them actually ended up with different values, despite the SET t1.user = t2.user command.
Warnings: 2017 says that something went wrong, and you should issue a SHOW WARNINGS query to find out what it was. In this case, the disparity between what can be stored in a smallint vs an integer meant that the data was being truncated in table_1.
Related
i have two tables named t1 and t2.
t1 have 500 rows and t2 have 220000 rows. the relationship between these tables are t1.t_id and t2.t1_t_id. not all t1 rows have corresponding row in t2.
now this line of code works fine
SELECT t1.t_id , t2.t1_t_id FROM t1, t2
where t2.t1_t_id = t1.t_id and t1.t_id=11
but this does not work
SELECT t1.t_id , t2.t1_t_id FROM t1, t2
where t2.t1_t_id = t1.t_id
in case picture not available
error is:
1 error were found during analysis
1. missing expression (near "ON" at position 25)
SQL query edit
set foreign_key_checks=on
mysql said
2006 server has gone away
what i want to do after solving this issue is:
t1 have a column named p_id which is primary.
i recently added a new column in t2 named t1_p_id.
now i want to update t2.t1_p_id = t1.p_id where t2.t1_t_id = t1.t_id.
i know i should use inner join on t2.t1_t_id = t1.t_id in a update query but it also issues the same error.
my guess for the error is that i should specify some specific condition because not all t1 have corresponding row in t2
update
i am querying by browser by mysql console
thanks
If I have two tables that I'm joining and I write the most simple query possible like this:
SELECT *
FROM t1
LEFT JOIN t2 ON t1.id = t2.id
There are a few records who have multiple rows per ID because they have multiple employers, so t1 looks like this:
ID Name Employer
12345 Jerry Comedy Cellar
12345 Jerry NBC
12348 Elaine Pendant Publishing
12346 George Real Estate
12346 George Yankees
12346 George NBC
12347 Kramer Kramerica Industries
t2 is linked with the similar IDs but with some activities that I'd like to see -- hence the SELECT * above. Though I don't want multiple rows to return if the Employer column is "NBC" -- but everything else is good.
The only other thing that matters here is that t2 is smaller than t1, because t1 is everybody and t2 are only from people who did particular activities -- so some of the matches won't return anything from t2, but I would still like them to be returned, hence the LEFT JOIN.
If I write the query like this:
SELECT *
FROM t1
LEFT JOIN t2 ON t1.id = t2.id
WHERE Employer <> "NBC"
Then it removes Jerry and George completely -- when really all I want is for the NBC row to not be returned, but to return any other rows that are associated with them.
How can I write the query while joining t1 with t2 to return each row except for the NBC ones? The ideal output would be all of the rows from t1 regardless if they match up with all of t2 except removing all of the rows with "NBC" as the employer in the return file. Basically the ideal here is to return the JOINs where they fit, but regardless remove the entire row for anybody with "NBC" as employer without removing their other rows.
The more I write about it, it seems like I should potentially just run a query prior to my JOIN to delete all the rows in t1 who have "NBC" as their employer and then run the normal query.
Basic subset filtering
You can filter either of the two merged (joined) subsets by extending the ON clause.
SELECT *
FROM t1
LEFT JOIN t2
ON t1.ID = t2.ID
AND t2.Employer != 'NBC'
If you get null values now, and you don't want them, you'd add:
WHERE t2.Employer IS NOT NULL
extended logic:
SELECT *
FROM t1
LEFT JOIN t2
ON (t1.ID = t2.ID AND t2.Employer != 'NBC')
OR (t2.ID = t2.ID AND t2.Employer IS NULL)
Using UNION
Basically, JOIN is for horizontal linking and UNION does vertical linking of datasets.
It merges to resultsets: the first without NBC, and the second (which is basically an OUTER JOIN), adds everyone in t1 which is not part of t2.
SELECT *
FROM t1
LEFT JOIN t2
ON t1.ID = t2.ID
AND t2.Employer != 'NBC'
UNION
SELECT *
FROM t1
LEFT JOIN t2
ON t1.ID = t2.ID
AND t2.Employer IS NULL
String manipulation in the resultset
If you just want to remove NBC as a string, here is a workaround:
SELECT
t1.*,
IF (t2.Employer = 'NBC', NULL, t2.Employer) AS Employer
FROM t1
LEFT JOIN t2
ON t1.id = t2.id
This basically replaces "NBC" by NULL
I've the following UPDATE statement
UPDATE Table1 t1
INNER JOIN Table2 t2 ON (t1.Day = t2.Day AND t1.Id = t2.Id)
SET
t1.Price = t2.Price,
t1.Name = t2.Name
WHERE t2.Id = 1
AND t2.Day = DATE_FORMAT(DATE_ADD('2013-11-01', INTERVAL 1 DAY),'%Y-%m-%d');
When running a EXPLAIN statement I get the message back as
Impossible WHERE noticed after reading const tables
At the moment selecting a range of 21 records is returned in about 0.400 seconds on average.
I've already added a Index on the fields t2.Id and t2.Day. Basically the requirement of this update statement is to take all records that exist in Table2 with the Id of 1 for each Day (or all Dates between DayStart and DayEnd, which I have access to).
Is there anyway on improving this in terms of performance, or should I not worry about the EXPLAIN result ?
I assume that
SELECT * FROM Table1 t1
INNER JOIN Table2 t2 ON (t1.Day = t2.Day AND t1.Id = t2.Id)
WHERE t2.Id = 1
AND t2.Day = DATE_FORMAT(DATE_ADD('2013-11-01', INTERVAL 1 DAY),'%Y-%m-%d');
will return an empty result.
Impossible WHERE noticed after reading const tables is not performance related. The EXPLAIN is just telling you that there is no dataset found with your given WHERE condition. So maybe there are no datasets in Table2 with Id = 1 OR Day = '2013-11-02'?
If you solved the Impossible WHERE... you can start optimizing your query with the EXPLAIN result (400ms seems to be very slow).
In my mysql I am having t1, t2 tables and I want to update t1's field from t2's field value based on t1's field value match t2's field value
I tried the below but it is not updating. What I did wrongly here
UPDATE t1
INNER JOIN t2
ON t1.name = t2.name
SET t1.age = t2.age
WHERE t1.name IS NOT NULL;
You need to separate the table you want to update from the table your querying, even though it is the same:
UPDATE t1
SET t1.age = t2.age
FROM t1 as tempT1
INNER JOIN t2
ON tempT1.name = t2.name
WHERE tempT1.name IS NOT NULL;
UPDATE
Apparently MySQL is using a different UPDATE JOIN Syntax than other db's. Your initial query seems to use the correct syntax, just to be sure try to alias the table names:
UPDATE t1 temp1
INNER JOIN t2 temp2
ON temp1.name = temp2.name
SET temp1.age = temp2.age
WHERE temp1.name IS NOT NULL;
UPDATE 2
After looking at this a bit longer I'm certain that the WHERE clause is the issue:
WHERE temp1.name IS NOT NULL
You cannot join on null values anyway, so they are filtered out by default. The WHERE clause is somehow interfering with the join.
Try and remove it to see if the UPDATEworks. If you don' t want to execute and update right away simply execute a select with the same JOIN CLAUSE to see which records would be affected.
Here is a general reference to NULL and JOIN:
http://databases.about.com/library/weekly/aa051203a.htm
Here is the SQL Server Reference in compliance with the above: http://msdn.microsoft.com/en-us/library/ms190409.aspx
Could not find a MySQL reference that states this explicitly but I think this is true for all Relational DBs.
I myself also found another way to achieve this same scenario. I am pasting the answer here so that others will get benefit.
UPDATE t1 SET t2_age = (SELECT age FROM t2 BINARY WHERE name = t1.name);
Try this:
update t1
set t1.age = t2.age
from t1
inner join t2 on t1.name = t2.name
where t1.name is not null
Try this
UPDATE t1,t2
SET t1.age = t2.age
FROM t1 as tempT1
INNER JOIN t2 ON tempT1.name = t2.name
WHERE tempT1.name IS NOT NULL;
I'm using MySQL 5.1.41 on ubuntu 12.10 and MySQL Workbench.
I have 2 product tables, t1 and t2. t1 is the live data and t2 is a imported data ready to be updated into t1 to update all the new product prices. So I run:
SELECT * FROM t1
JOIN t2 ON t1.id = t2.id
WHERE t1.price != t2.price;
This returns 1201 records where the price is different and needs to be updated. So I run:
UPDATE t1 JOIN t2 ON t1.id = t2.id
SET t1.price = t2.price
WHERE t1.price != t2.price;
This completes without error and reports 1143 row(s) affected, Rows matched: 1143 Changed: 1143 Warnings: 0
So already something here is not right. 1201 records were different in the select query, but only 1143 changed using the same join and criteria?
Running the initial select query I'd expect to see 58 records that still had different prices. But when running it I get the same 1201 as I did initially. It's as if the updates are not being committed.
Any ideas?
The number (1201) that your SELECT shows is not records of t1 but rows from the JOIN of two tables. If the two id are not both UNIQUE or PRIMARY KEYs then this is expected. Some rows of t1 match multiple rows from t2. But when the UPDATE is done they are only updated once (this is a MySQL "feature" or "bug" of UPDATE that checks WHERE conditions sequentially during an update statement.
Try this to see how many rows (of t1) should be updated:
SELECT * FROM t1
WHERE EXISTS
( SELECT *
FROM t2
WHERE t1.id = t2.id
AND t1.price != t2.price
);