MySQL event variables - copy value to another table - mysql

DELIMITER |
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
DO
BEGIN
DELETE FROM vehicle WHERE last_updated < (NOW() - INTERVAL 5 MINUTE)
END |
DELIMITER ;
Above I have a MySQL event that runs every minute deleting rows that haven't been updated for 5 minutes. I have another table called saved_vehicles. All of the rows in vehicle will have a row in the saved_vehicle table. What I want to do is essentially copy over the last_updated time to the saved_vehicle table (for example purposes, imagine the saved_vehicle field would be last_known_online_time. This essentially saves a copy of the vehicle with its last known online time.
Essentially I'm creating a backup before deleting the row.

Insert into saved_vehicles before delete.
Try this:
DELIMITER |
CREATE EVENT myevent
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
DO
BEGIN
SET #time = NOW() - INTERVAL 5 MINUTE;
# select * is not very smart, it will also copy your primary key,
# so you can get error about duplicates. Listing fields would work here.
INSERT INTO saved_vehicle (SELECT * FROM vehicle WHERE last_updated < #time);
DELETE FROM vehicle WHERE last_updated < #time;
END |
DELIMITER ;
To avoid listing fields i've mentioned in comment try to select all fields except your primary key column.
To do this check how to select all columns except one
update
I through about insert i mentioned above - and if your saved_vehicle table has same structure as vehicle table, but its primary key has different name than vehicle (f.e. base_id, when vehicle PK is id) and its int auto_increment then it will work nice as it is.

Related

Updating both parent and child table in stored procedure

MySQL Version: '5.7.37-0ubuntu0.18.04.1'
I have the goals of
Updating rows in table ost_ticket after one week of no new activity
Update or Insert into table ost_ticket__cdata one row for each row updated in ost_ticket
I will be using MySQL Event Scheduler to call the code that will accomplish the above two goals on an hourly basis.
My tendency is to put the code in a stored procedure, which is then called by the event scheduler.
My challenge is that I'm not sure how to transition from goal 1 to goal 2. How can I Update / insert into the child table for only those rows affected on the parent table, and only as a result of the event scheduler job (in other words, I don't want to use a trigger any time the parent table is updated, only when the "one-week-old" condition is satisfied)
Draft of the stored procedure with my rambling commentary is below...
USE `osticket`;
DROP procedure IF EXISTS `AutoClose';
DELIMITER //
Create Procedure AutoClose ()
Begin
# GOAL 1: UPDATE ROWS THAT ARE ONE WEEK OLD...
UPDATE ost_ticket t
SET
t.status_id = 3, # 3 = "Closed"
t.closed = date_add(t.lastupdate, interval 7 day),
t.updated = date_add(t.lastupdate, interval 7 day)
t.lastupdate = date_add(t.lastupdate, interval 7 day),
WHERE t.status_id = 2 # 2 = "Resolved"
AND now() >= date_add(t.lastupdate, interval 7 day);
# GOAL 2: UPSERT ADDITIONAL INFORMATION ON CHILD TABLE
# DONT THINK THIS WILL WORK HERE... HOW DO I RUN THE FOLLOWING CODE
# FOR EACH ROW AFFECTED BY THE UPDATE ABOVE?
INSERT INTO ost_ticket__cdata (ticket_id, subject, priority, autoclosed)
ON DUPLICATE KEY UPDATE autoclosed = '1';
values
(x, y, 2, 1)
End //
DELIMITER;

MySQL event or trigger to automatically update a value 30 minutes after last modify

I have in my DB (db_test) a table (tb_test) with 3 columns (id, test_field, timestamp_ins, timestamp_mod).
id is the 'primary key' with auto-increment attribute;
test_field is a char(1) that can contains only 2 values ('N' or 'S');
timestamp_ins is a datetime with current timestamp (not updating);
timestamp_mod is a datetime with current timestamp set to ON UPDATE CURRENT_TIMESTAMP().
I would like test_field automatically returns to default value ('N') 30 minutes after last modify of record indicated in timestamp_mod value.
I'm not expert in mysql, so I need help about this.
Is it possible using phpMyAdmin on a XAMPP virtual server?
--UPDATE--
Solved with this syntax:
CREATE EVENT IF NOT EXISTS test_event
ON SCHEDULE EVERY 1 MINUTE
DO
UPDATE ni0y2__test
SET test_field = DEFAULT
WHERE test_field < NOW() - INTERVAL 30 MINUTE
Only one doubt:
can this event make my DB performances worse?
I prefer putting the onus on the reader, not the table:
SELECT IF (timestamp_mod < NOW() - INTERVAL 30 MINUTE,
'N',
test_field) AS funky_field
FROM tb_test;
EVENTs have some overhead. Also, the above method will change at precisely 30 minutes; any attempt at using EVENT will be only approximately 30.
You could "hide" the IF(...) from the users by using a VIEW or Stored Function or a GENERATED column.

Creating A MySQL event procedure which inserts a new record into database every day for each employee id in another table

Good Day
I have two tables named as Users and mileagesnew
The users table has an id which is unique (Primary Key) and the users.id column acts as a foreign key in the mileagesnew table.
The Users Table
The mileagesnew Table
I want to create a MySQL event to insert a new mileage record for each and every user in the Users table inside the mileagesnew table
So, the MySQL trigger i have right now is,
CREATE EVENT Daily_Mileage
ON SCHEDULE
EVERY 1 DAY
STARTS (TIMESTAMP(CURRENT_DATE) + INTERVAL 1 DAY + INTERVAL 1 HOUR)
DO
INSERT INTO `mileagesnew`(`user_id`, `date`, `mileage`, `fuel_mileage`, `fuel`, `fuel_cost`, `km`,
`kmpl`, `remarks`, `created_at`, `updated_at`) VALUES
('Need To Get The ID of every employee in users table here without
repeating',CURRENT_DATE,'0','0','0','0','0','0','0','',CURRENT_TIMESTAMP,CURRENT_TIMESTAMP);
I am not sure how i can get the id value of each records present in the users table without having any duplicates. Is this possible or if i am doing this via mysql should i write the query individually for all users
So far the event set will run only for one user id but not for other which is set as follows,
CREATE EVENT Daily_Mileage
ON SCHEDULE
EVERY 1 DAY
STARTS (TIMESTAMP(CURRENT_DATE) + INTERVAL 1 DAY + INTERVAL 1 HOUR)
DO
INSERT INTO Mileages (user_id, `date`, mileage, fuel_mileage, fuel, fuel_cost, km, kmpl, remarks)
SELECT id, CURRENT_DATE, 0, '0', '0', '0', 0, 0, ''
FROM Users;
PS. created_at and updated_at columns are already DEFAULT CURRENT_TIMESTAMP, so they're removed. Single quotes wrapped zeros for numeric columns are removed.
PPS. TIMESTAMP function usage in STARTS is excess, STARTS CURRENT_DATE + INTERVAL '1 1' DAY_HOUR is enough.
the table name is mileagesnew not Mileage – Developer
Adjust it in the query by yourself.

Select one piece of data from every day at a specific hour MySQL

My database has data imputed every 1 minute and is stored in the format 2020-04-05 16:20:04 under a column called timestamp.
I need a MySQL query to select data from every day at a specific hour (the second does not matter), for for example I want to get the data from 16:00 of every day from the past 30 days.
It currently, just grabs the data from the past 30 days and then the PHP application sorts it, however, this is causing very slow loading time, hence wanting to only select the wanted data from the database.
Example of data
Please try the following sql:
select
d.timestamp, hour(d.timestamp)
from
demo1 d
where
DATEDIFF(NOW(), d.timestamp) < 30 and hour(d.timestamp) = 16;
The create sql is as following:
CREATE TABLE `demo1` (
`id` int(11) not null auto_increment primary key,
`serverid` int(11) not null,
`timestamp` datetime not null,
KEY `idx_timestamp` (`timestamp`)
) engine = InnoDB;
insert into `demo1` (serverid, timestamp)
VALUES (1, "2020-07-05 16:20:04"),
(2, "2020-07-06 17:20:04"),
(3, "2020-07-07 16:40:04"),
(4, "2020-07-08 08:20:04"),
(5, "2020-07-05 15:20:04"),
(5, "2020-07-05 16:59:04"),
(5, "2020-06-04 16:59:04");
Zhiyong's response will work, but wont perform well. You need to figure out a way to get the query to use indexes.
You can add a simple index on timestamp and run the query this way:
SELECT
d.timestamp, d.*
FROM demo1 d
WHERE 1
AND d.timestamp > CURDATE() - INTERVAL 30 DAY
AND hour(d.timestamp) = 16;
In MySQL 5.7 and up, you can created a generated column (also called calculated column) top store the hour of the timestamp in a separate column. You can then index this column, perhaps as a composite index of hour + timestamp, so that the query above will perform really quickly.
ALTER TABLE demo1
ADD COLUMN hour1 tinyint GENERATED ALWAYS AS (HOUR(timestamp)) STORED,
ADD KEY (hour1, timestamp);
The result query would be:
SELECT
d.timestamp, d.*
FROM demo1 d
WHERE 1
AND d.timestamp > CURDATE() - INTERVAL 30 DAY
AND hour1 = 16;
More info on that here:
https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html
https://dev.mysql.com/doc/refman/5.7/en/generated-column-index-optimizations.html

SQL - insert new row depends on previous data from same table

I have a table with Car name. Here is a pseudo-table :
This table has been fallen with data like :
order = 14214
type = 0
created = 2017-12-10 23:39:23
I want to some operation with this data :
1 - find data till 6 days ago.
2 - (For each records of step 1)
I want to insert new record with order same as step1.order and with type= 1.
For first step , I found out I use
select *
from cars
WHERe `created` <= Date(Now()) - INTERVAL 6 day
but for next step, Is there any suggestion?
EDITED: :
Ex . I had a table with 250 records, after inserting new data, my table would be 500 rows with A table and A' (B&B',...) for each order.
You can try as below script.
Note: I assume ID field is auto-increment primary key.
insert into cars (`order`, type, created)
select `order`, 1 type, created
from cars
WHERe `created` <= Date(Now()) - INTERVAL 6 day
Hope it can help.