The table contains the columns id, timestamp (eg. 2013-09-23 12:10:53), activity and I want to add another column duration which would contain the duration of each activity (ie. the difference between the next row time stamp and the current one).
I've tried this query:
UPDATE `MyTable` this SET `duration`=
(SELECT DATEDIFF(next.`timestamp`, curr.`timestamp`)
FROM `MyTable` curr
JOIN `MyTable` next
ON next.`id` = curr.`id`+1
WHERE this.`id` = curr.`id`)
And got this error:
#1093 - You can't specify target table 'this' for update in FROM clause
How can I go about doing that?
Instead, use a join:
UPDATE MyTable this left join
MyTable next
ON next.id = this.id + 1
SET this.duration = DATEDIFF(next.timestamp, this.timestamp) ;
I think the error is self-explanatory. The usual solution in MySQL is to convert the update to use joins instead of correlated subqueries.
Some reference for you
You can't specify target table for update in FROM clause
http://dev.mysql.com/doc/refman/5.0/en/update.html
UPDATE `MyTable` this SET `duration`=
(SELECT DATEDIFF(next.`timestamp`, curr.`timestamp`)
FROM (SELECT * from MyTable) curr
JOIN (SELECT * from MyTable) next
ON next.`id` = curr.`id`+1
WHERE this.`id` = curr.`id`);
Related
Below is a MySQL query:
SELECT
COUNT(*) AS counted, employer_group
FROM
employer_survey
GROUP BY employer_group
HAVING counted > 1;
Before I alter table definition for employer_group to unique, I need to create an UPDATE statement to CONCAT() the value of created_dt to employer_group so the alter table will not fail because of values.
How do I do this? I am unable to return id column because I am using GROUP BY and HAVING.
I should mention that I want the id column returned so I may use the above SELECT with an IN clause in my UPDATE statement. This may not be the best approach.
You can do this with join:
update employer_survey es join
(select es2.employer_group
from employer_survey es2
group by es2.employer_group
having count(*) > 1
) eg
on es.employer_group = eg.employer_group
set es.employer_group = concat_ws(' ', es.employer_group, es.created_dt);
I'm looking for a simple way to do an update on a table only if there is no other columns present in that same table with the same value I'm trying to update, ideally in a single query. So far I'm getting an error You specify target table 't1' for update in FROM clause. Here is what I tried in a few variations so far (still unable to get working):
UPDATE emailQueue AS t1
SET
t1.lockedOn = 1470053240
WHERE
(SELECT
COUNT(*)
FROM
emailQueue AS t2
WHERE
t2.lockedOn = 1470053240) = 0
AND t1.lockedOn IS NULL
In MySQL, you need to use a join. In this case, a left join is in order:
UPDATE emailQueue eq LEFT JOIN
emailQueue eq2
ON eq2.lockedOn = 1470053240
SET eq.lockedOn = 1470053240
WHERE eq.lockedOn IS NULL AND
eq2.lockedOn IS NULL;
I know there are a lot of topics on this but I can't figure out how should I rewrite my query to make it work :(
Here my query. It's just should take currency rate from other table and calculate cost
update site_s_client_base_price
SET calculated_price_in_base_currency =
SELECT (site_s_currencies.rate * site_s_client_base_price.supplier_price) from
site_s_currencies, site_s_client_base_price
WHERE site_s_currencies.currency_id=site_s_client_base_price.currency_id
Please, help me with this
You can't seletc and update in the same table because it's locked, use the example above or use
Update TABLE1 t1 set FIELD1= ( select field1 from TABLE1 t2 where .....)
In your case you can fix this by fixing the subquery. You don't need to mention the outer table in the inner from clause. You want a correlated subquery:
update site_s_client_base_price bp
SET calculated_price_in_base_currency =
(SELECT c.rate * bp.supplier_price
FROM site_s_currencies c
WHERE c.currency_id = bp.currency_id
);
I have: something like
UPDATE table
SET field = (SELECT field FROM another_table WHERE id = #id);
Problem: SELECT field FROM another_table WHERE id = #id subquery can return one field or EMPTY SET.
Question: How to handle situation when subquery returns empty set?
Updated:
UPDATE table t
SET field = IF((SELECT field FROM another_table WHERE id = #id) IS NOT NULL, -- select field
(SELECT field FROM another_table WHERE id = #id), -- Problem #1: select field AGAIN!
(SELECT field FROM table WHERE id = t.id) -- Problem #2: try to not change value, so select the current field value!!
);
If function can be useful:
UPDATE table
SET field = if((SELECT field FROM another_table WHERE id = #id) IS NULL,true,false);
You can add the conditional:
WHERE (SELECT COUNT(*) FROM another_table WHERE id = #id) > 0
This will make sure that at least one row exists in another_table with the id. See my SQL Fiddle as an example.
Note: this may not be the most efficient because it does a count on another_table, and if it is greater than 1 it will do another SELECT (two sub-queries). Instead, you can do an INNER JOIN:
UPDATE table
INNER JOIN another_table ON table.id=another_table.id
SET table.field = another_table.field
WHERE another_table.id = #id;
See this SQL Fiddle. The reason why I saved this as a second option, is not all SQL languages can UPDATE with joins (MySQL can). Also, you need some way to relate the tables..in this case I said that the table.id we are updating is equal to another_table.id we are taking the data from.
NOTE The UPDATE statement will modify EVERY row in table and assign the same value to every row; that seems a little unusual.
To answer your question:
If you want to handle the "empty set" by not updating any rows in table, then one way to do this is with a JOIN to an inline view:
UPDATE table t
CROSS
JOIN (SELECT a.field
FROM another_table a
WHERE a.id = #id
LIMIT 1
) s
SET t.field = s.field
Note that if the inline view query (aliased as s) return an "empty set", then no rows in table will be updated, because the JOIN operation will also return an "empty set", meaning there are zero rows to be updated.
Modified some stuff from my pic so you guys can understand it
I have this database. I am trying to update a value from a table based on another value from an another table.
I want to update the SUM from salary like this :
( sum = presence * 5 )
This is what I've been trying to use ( unsuccessful )
update table salary
set suma.salary = users.presence * 5
FROM salary INNER JOIN users1 INNER JOIN presence on id_salary = id_presence
I am not sure what to do, I'd appreciate some help, Thanks
In MySQL to UPDATE tables with a join you use this syntax:
UPDATE table1, table2
SET table1.column = some expression
WHERE table1.column = table2.column
That said, even with the updated picture, in your SQL you are mentioning columns that I cannot understand in which table are to be found. You also have an inner join between salariu and users1, with no join condition. Could you please clean up the question and make everything clear?
Assuming you are making the updates to the db structure you were talking about, then you can start working on this one maybe:
UPDATE salary, presence
SET salary.sum = SUM(presence.hours) * 5
WHERE presence.id = salary.id
AND <some filter on the month that depends on salary.date>
Another way, but I'm not sure it is supported in all RDBMS, would be something like this:
UPDATE salary
SET sum = (
SELECT SUM(presence.hours) * 5
FROM user, presence
WHERE presence.id = salary.id
AND <some filter on the month that depends on salary.date>
)