Update mysql cell after fetching related cell value via select? - mysql

SQL:
$mysqli->query("UPDATE results
SET result_value = '".$row[0]['logo_value']."'
WHERE logo_id = '".$mysqli->real_escape_string($_GET['logo_id'])."'
AND user_id = '".$user_data[0]['user_id']."'");
This results table also contains result_tries I'd like to fetch before doing update, so I can use it to modify result_value... Is there a way to do it in a single shot instead of first doing select and than doing update?
Is this possible?

Basically:
UPDATE results SET result_value = result_value + $row[0][logo_value]
for just a simple addition. You CAN use existing fields in the record being updated as part of the update, so if you don't want just addition, there's not too many limits on what logic you can use instead of just x = x + y.

Related

Update multiple rows with random timestamp [duplicate]

I currently have an oracle table (lovalarm) containing around 600,000 rows. I need to be able to run a query which will cycle through each row and update a field (lovsiteid) to a random number between 14300 and 17300.
So far I have:
update lovalarm
set lovsiteid = (select TRUNC(dbms_random.value(14300,17300)) FROM dual)
Sadly this picks a random number and then updates all rows with the same number which isn't exactly what I'm after!
Can anyone point me in the right direction?
Many thanks,
Cap
Just not use subquery:
update lovalarm
set lovsiteid = TRUNC(dbms_random.value(14300,17300))
Try this:
update lovalarm set lovsiteid = (select FLOOR(RAND() * (17300 - 14300) + 14300))
works in MySQL

Select column to update based on value

What I am trying to do is reduce the time needed to aggregate data by producing a roll-up table of sorts. When I insert a record, an after insert trigger is fired which will update the correct row. I would update all of the columns of the roll-up table if I need to, but since there are 25 columns in the table and each insert will only update 2 of them, I would rather be able to dynamically select the columns to update. My current update statement in the after insert trigger looks similar to this:
update peek_at_chu.organization_data_state_log odsl
inner join ( select
lookUpID as org_data_lookup,
i.interval_id,
peek_at_chu.Get_Time_Durration_In_Interval1('s', new.start_time, new.end_time, i.start_time, i.end_time) as time_in_int,
new.phone_state_id
from
(peek_at_chu.interval_info i
join peek_at_chu.interval_step int_s on i.interval_step_id = int_s.interval_step_id)) as usl on odsl.org_date_lookup_id = usl.org_data_lookup
and odsl.interval_id = usl.interval_id
set
total_seconds = total_seconds + usl.time_in_int,
case new.phone_state_id
when 2 then
available_seconds = available_seconds + time_in_int
end;
In this, lookUpID is a variable previously declared in the trigger. The field that will dictate which field of the roll-up table to update is new.phone_state_id. The phone_state_id's are not consistent, that is some numbers are skipped in this table, so an update based on column number is out the window unless I create a mapping.
The case option throws an error but I am hoping to use something similar to that instead of 25 if statements if I can.
You have to update all the columns, but use a conditional to determine whether to give it a new value or keep the old value:
set total_seconds = total_seconds + usl.time_in_int,
available_seconds = IF(new.phone_state_id = 2, available_seconds + time_in_int, available_seconds)
Repeat the pattern in the last line for all the other columns that need to be updated conditionally.

MySQL Get "id" from select

I have a select statement:
SELECT id, content, name
FROM records
WHERE type = '1'
AND name = 'test';
Here's the output:
id content name
99708 10.6.252.41 server01.example.org
What I'd like to do is be able to get the id that is returned from the previous statement and USE the id as input into another statement (an UPDATE statement) that will increment the value of a single column in the same table.
An example UPDATE statement that I am wanting is:
update records SET hits = hits + 1 WHERE id = ID_FROM_SELECT;
Thanks in advance.
You can use user defined session variables for this if the SELECT is returning just one result:
SELECT #id:=id AS id, content, name
FROM records
WHERE type = '1'
AND name = 'test';
Then, on the same database session (connection), do the following:
UPDATE records
SET hits = hits + 1
WHERE id = #id;
I'm assuming you're doing something with the selected records in your app, and you're trying to save on performance by avoiding having to search for the record again in the UPDATE. Though, in that case, why not set the 'id' value as a parameter in code?
Obviously, if the SELECT is returning multiple records, this would best be done in code as I mentioned above, otherwise you're left with running the SELECT query again as a subquery:
UPDATE records
SET hits = hits + 1
WHERE id IN
(SELECT id
FROM records
WHERE type = '1'
AND name = 'test');
So, then, it makes more sense just to apply the same filter to the UPDATE instead:
UPDATE records
SET hits = hits + 1
WHERE type = '1'
AND name = 'test'
Probably this is not what you want to do.
First of all...If the query only returns 1 line, the solution provided by Marcus Adams works fine. But, if the query only returns one line, you dont need to preset the id in order to update. Just update it:
update records
set hits = hits + 1
where type = '1'
and name = 'test'
Second...If the query will not return only one record and you want to update all records returned with same values or calculations, the same code above will do what you need.
Third, if the query does not return just one record and you need to update each record returned with different value then you need to have a different approach.
I think you are not designing your system very well. If the request for update come from outside, you should have the id to be updated as a parameter of your request. For example something like:
<html>
<body>
Test
</body>
</html>
And in your update.php you have something like:
<?php
$id = $_GET['id'];
$sql = "update records set hits = hits + 1 where type = '1' and name = 'test' and id = $id";
?>
Of course, the picture I have is to small. Probably you have a reason to do this way or this is just an example. If you fill us up with more info we might be more helpful.

Order of execution of SQL UPDATE while updating multiple values?

What is the sequence in which the values (separated by commas) will be updated?
$command = sprintf('UPDATE %s SET rating = ((rating * rating_count + %f) / (rating_count + 1.0)) , rating_count=rating_count+1 WHERE id=%d', $table, $ratingGiven, $id)`;
I want to make sure that
rating = (rating * rating_count + %f) / (rating_count + 1.0)
is executed before
rating_count=rating_count+1
without firing two SQL commands.
I am not sure if the update-value-statements are executed in the order in which they are separated by commas in MySql (or any other DB)?
I don't think it will matter UPDATE will read the current row and do the update upon it based on the existing values, and not the ones that are in the update.
So in both SET operations, the original value of rating_count will be used.

Update MySQL column based on multiple values

How can I modify this statement to set the region value where there are multiple values in the location_town column?
UPDATE `wp_em_locations` SET `location_region` = 'The-Valley'
WHERE `location_town` = 'Bond'
IE: Bond is not the only town, I have many town names but all should be used to set location_region = The-Valley.
How do I accomplish this using one statement? Or do i need to run the same statement for each town name?
You can use either an OR or IN statement
WHERE `location_town` IN ('Bond', 'OtherTown')
or (no pun intended)
WHERE `location_town` = 'Bond' OR `location_town` = 'OtherTown'
Is the statement more complex than this? if you're trying to set every row to have location_region set to 'The-Valley' why use the where clause, which only serves to limit the scope of the update query?
Would this do what you're looking for, are am I misunderstanding?
UPDATE `wp_em_locations` SET `location_region` = 'The-Valley' WHERE 1;