Updating data in MySQL in scheduled time - mysql

I want to UPDATE my data in scheduled time. My problem is that I cant equal the date that I enter in my database in the current real time date. For example, I have 2015/24/9 19:50:00 in my database, now I want to equal it to the current real time date so that I can update a specific row in the database. If I don't do that, the amount field will just multiply 5 in every row. I want to multiply the amount by 5 in a specific row and time
Code:
CREATE EVENT myeventsdasa11s
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
ON COMPLETION PRESERVE
DO
UPDATE messagesd
SET amount = amount*5
WHERE DATE = (the the current real time date);

DATETIME and TIMESTAMP values are, like floating-point values, difficult to compare for numerical equality. In other words, if it happens that NOW() = datetimestamp, it's a lucky accident. This is especially true when processing events: the event actually starts to run shortly after the scheduled time.
So, instead of saying something like this
`DATE` = NOW()
say something like this
`DATE` BETWEEN NOW() - INTERVAL 10 SECOND
AND NOW() + INTERVAL 10 SECOND
Of course, such a narrow time interval makes you critically dependent on the time accuracy of the event scheduler. You'd be better off adding a LAST_UPDATED column of DATETIME type to your table, then doing this update.
UPDATE messagesd
SET amount = amount * 5,
LAST_UPDATED = `DATE`
WHERE `DATE` >= NOW() - INTERVAL 1 MINUTE
AND (`DATE` > LAST_UPDATED OR LAST_UPDATED IS NULL)
That way, every time your event runs you'll update all the rows that are due for update, but haven't yet been updated. This is not dependent on the precise time an event runs. The - INTERVAL 1 MINUTE allows the event to be up to a minute late running and still function correctly.
If you need to schedule another update for the future for a particular row, change the value of the DATE column but don't touch the LAST_UPDATED column.

Are you just looking for CURDATE()?
CREATE EVENT myeventsdasa11s
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
ON COMPLETION PRESERVE
DO
UPDATE messagesd
SET amount = amount * 5
WHERE DATE = CURDATE();

If you need the current real date time use mysql NOW()
CREATE EVENT myeventsdasa11s
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
ON COMPLETION PRESERVE
DO
UPDATE messagesd
SET amount = amount*5
WHERE DATE = NOW();

Related

Change column value if date is older than 1 hour in mysql/mariadb?

Say I have below SQL table:
+------------+---------------------+
| Status | Date |
------------+---------------------+
| Available | 2020-12-19 18:03:42 |
+------------+---------------------+
Basically I want MySQL to check the Date column every 3 minutes and if Date value is older than 1 hour, I want to change Status to Offline. Can we achieve such thing in SQL? Alternatively if there is easier solution in Django python, I am open to use that as well.
I would recommend doing this with a view:
create view v_t as
select (case when date + interval 1 hour < current_timestamp then 'Offline'
else status
end) as status,
. . . -- whatever other columns you have here
from t;
A view has the following advantages:
The value is automatically correct. Users of the view will see the 'Offline' status exactly after an hour.
There is no overhead on changing the data.
This works even if the entire system goes down and then comes back up.
You can actually set the status at your leisure -- say a job that runs once per day or per week at an off-time.
You can check and update the status in a single statement:
update mytable set status = 'Offline'
where date < current_timestamp - interval 1 hour;
Now we need to schedule the query to execute on a regular basis. For this, one would typically use MySQL's event scheduler:
create event event_update_status
on schedule every 3 minute
starts current_timestamp
ends current_timestamp + interval 1 day
do
update mytable set status = 'Offline'
where date < current_timestamp - interval 1 hour;

How can I update value every 20 and 30 minutes?

I have a table ‘comenzi’, each order has a value for in progress, and another for ready and data. Each order when it is created has the values for in progress and ready equal to 0. I want to update the values for in progress and ready with 1 min ,after 20 min, then 30 min after the order has been done, the value from data that has the form 2020-05-25 09:41:00.
I need a way to update these values, a function or an event in database.
I was dealing with something using events just yesterday on a pet project. You could use a similar approach.
This code uses a creation column, which is just a TIMESTAMP column with a default value of CURRENT_TIMESTAMP (because I don't have your data) and a value column (default value 0), which goes from 1 - 2 (you can modify this code to suit your needs).
The SET value uses CASEs to check how long ago the order was created. Then it updates the value accordingly. You can change up the event to update whichever columns / time cases you'll need.
CREATE DEFINER =`root`#`localhost` EVENT `progressEvent`
ON SCHEDULE EVERY 1 MINUTE STARTS '2020-09-01 00:00:00'
ON COMPLETION PRESERVE ENABLE DO UPDATE comenzi
SET `value` = (
CASE WHEN (creation < (CURRENT_TIMESTAMP - INTERVAL 30 MINUTE))
THEN 2
CASE WHEN (creation < (CURRENT_TIMESTAMP - INTERVAL 20 MINUTE))
THEN 1
END)
WHERE value < 2
Edit: Changed it up so that it checks every minute and only 20/ 30 minutes.

Selecting dates from MySQL using NOW() with Time Zone mutates results

I'm using a Laravel application that inserts timestamps based upon 'timezone' => 'America/New_York'. All of my data inserted is the correct date time. Which should be expected. I know that the MySQL's own timezone setting doesn't effect the inserted data.
However, I want to retrieve records from 30 mins ago. But when I use MySQL NOW() function its the wrong time. So I set the time_zone to America/New_York that gives me the correct NOW() but all the record dates have been mutated.
SELECT id, updated_at FROM my_table Where id = 6;
Gives me the correct date in my update_at field;
So to select my records within the past 30 mins is use:
SET #PAST_TIME = DATE_SUB(NOW(), INTERVAL 30 MINUTE);
SELECT id, updated_at, #PAST_TIME as past_time FROM my_table Where updated_at >= #PAST_TIME;
Which returns practically every record in my set and as you can see, the past_time is incorrect (I ran this at 9:31 ET).
Recognizing that the time mysql is out of sync, I set the timezone to
SET time_zone = 'America/New_York';
SET #PAST_TIME = DATE_SUB(NOW(), INTERVAL 30 MINUTE);
SELECT id, updated_at, #PAST_TIME as past_time FROM my_table Where updated_at >= #PAST_TIME;
Which outputs the correct PAST_TIME but all the update_at records are mutated. But it shouldn't return some of those records anyway because the mutated results are greater than PAST_TIME
How do I stop the column mutation? while still being able to select my records?
You can think of a timestamp column as essentially storing a UTC date and time. It really does not matter what the session time zone setting was when the timestamp value was stored if you are initializing it with a function such as now() or current_timestamp(); the date and time will be interpreted in the current time zone and converted to UTC (of course, now() returns a value that is time zone dependent but regardless of what the current session time zone is you should end up with the same UTC date and time after conversion). However, how the timestamp is displayed very much depends on what the current session time zone is, for the timestamp will be converted back from UTC to whatever the current time zone in effect is.
(On the other hand, if you have a datetime column initialized with now() what will be stored will very much depend on the current time zone because there is never any time zone conversion done. But then it will always be displayed the same regardless of what the current session time zone is in effect.)
When you want to retrieve records that were updated within the last 30 minutes, it's natural to have in your query somewhere DATE_SUB(NOW(), INTERVAL 30 MINUTE). When you are comparing NOW() or a value computed from NOW() with a timestamp column, again it should not make any difference what the current time zone is. The timestamp column has implicit time zone information (UTC) and you should retrieve the same records regardless. As I would expect, I see exactly the same id values being retrieved before and after you set the America/New_York time zone (one might see some difference due to the time lapse between the two queries; fewer rows might now have been updated in the last 30 minutes). The difference, which is to be expected, is how the dates and times are displayed.
You do want to set the America/New_York time zone just so the dates and times jive with your local time. But you should still be getting the same records regardless.

How to UPDATE data in MySQL after a scheduled time

I am new to SQL and I want to update the Amount in the amount field. For example in every month in 3 months I want to add 100 to THE 500 in the amount field in the database. And when the 3rd month comes It will automatically transfer the data to another table
This is the the code I have done so far, but its not working
CREATE EVENT myevent
ON SCHEDULE EVERY 1 MINUTE
STARTS CURRENT_TIMESTAMP
ENDS CURRENT_TIMESTAMP + INTERVAL 2 MINUTE
DO
UPDATE message
SET amount*3
WHERE date = NOW();
Try to change the update command into:
UPDATE Message
SET amount = amount + 100
WHERE DATEDIFF(CURDATE(), date) >=value

Date Interval Bug

I have a table which has a column called created DATETIME, When adding entries It works fine, but when It gets to Date Interval, It keeps on duplicating new entries. I'm trying to get Today's and Yesterday's entries. Today's works fine, but for Yesterday's, It also puts on Today's contents in query results which Is not what I want.
SELECT * FROM tab WHERE created > DATE_SUB(NOW(), INTERVAL $num DAY) ORDER BY created DESC LIMIT 9;
$num Is 1 for Today's entries, and It's 2 for Yesterday's. So basically an entry which Is created today, Is getting duplicated on Yesterday's query results.
You are getting the results you requested from the database. Namely any record that is greater than today minus however many days you put in.
The reason you get 0 records when you try #KenWhite's suggested of changing your > to = is because your field is DATETIME, so subtracting exactly 24 hours from NOW() yields the same exact time yesterday and you probably don't have a record that was written precisely at this time yesterday. Right?
What you'll have to do is test for records between two dates to get you want. Instead of NOW(), switch to CURDATE(), this way you can be assured you'll get every record for the datetime range you are looking for.
SELECT *
FROM tab
WHERE
created BETWEEN DATE_SUB(CURDATE(), INTERVAL $num DAY) AND DATE_SUB(CURDATE(), INTERVAL $num - 1 DAY)
ORDER BY created DESC LIMIT 9;
You can check out a SQLFiddle of this here: http://sqlfiddle.com/#!2/19d9b/12
With datetime/timestamp values, similar to floats, always use ranges with closed beginnings and open endings. So use '>=' and '<'.
For example to use the data of a single day:
SELECT ... FROM tab
WHERE created >= CURDATE() - INTERVAL #num:=? DAY
AND created < CURDATE() - INTERVAL #num DAY + INTERVAL 1 DAY
ORDER BY created DESC
LIMIT 9
;
With MySQL, generally prefer the timestamp type over the datetime type, as datetime doesn't carry timezone information.
Alternatives:
created_at timestamp NULL DEFAULT NULL COMMENT 'set by application',
created_at timestamp NOT NULL DEFAULT '1970-01-01 23:00:00' COMMENT 'set by application',
dbms_row_created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'set by DBMS',