I have a table (sessions) which has 2 columns that I have to use for this query.
Session_Active (which is a tinyInt) and Last_active(which is a datetime).
I want to create a query that calculates the time difference between now and 'Last_active' for all tables WHERE 'Session_Active' is true, and if its greater than 5 minutes it should change 'Session_Active'.
This is the part that I have which works:
SELECT timediff(now(), `Last_Active`) from sessions WHERE `Session_Active` = true;
I have no clue at all how I can check if the difference is greater than 5 minutes, neither do I know where/how to put the UPDATE Session_Active = false (If the difference is 5 minutes or more)
Thanks in advance! (:
You can use the following solution using DATE_SUB:
UPDATE sessions SET `Session_Active` = 0
WHERE `Last_Active` <= DATE_SUB(NOW(), INTERVAL 5 MINUTE)
AND `Session_Active` = 1
You want to use a timestamp solution?
You can use TIMESTAMPDIFF:
UPDATE sessions SET `Session_Active` = 0
WHERE TIMESTAMPDIFF(MINUTE, `Last_Active`, NOW()) >= 5
AND `Session_Active` = 1
Note: You should be careful with using TIMESTAMP! Some information why you shouldn't use TIMESTAMP: https://stackoverflow.com/a/35469149/3840840. On this answer there is a reference to this article describing the performance of DATETIME, TIMESTAMP and INT.
The TIMESTAMP solution is only working until 2038. This will be caused by the Year 2038 problem.
A very good explanation of this problem and what is happening in 2038: https://stackoverflow.com/a/2012620/3840840
You can use UNIX_TIMESTAMP(date)
When UNIX_TIMESTAMP() is called with a date argument, it returns the value of the argument as seconds since '1970-01-01 00:00:00' UTC. The date argument may be a DATE, DATETIME, or TIMESTAMP string, or a number in YYMMDD, YYMMDDHHMMSS, YYYYMMDD, or YYYYMMDDHHMMSS format. The server interprets date as a value in the current time zone and converts it to an internal value in UTC. This is faster then DATE_SUB on large table set.
UPDATE sessions
SET `Session_Active` = 0
WHERE UNIX_TIMESTAMP(now()) - UNIX_TIMESTAMP(`Last_Active`) > 300
AND `Session_Active` = 1
Related
i looking for some help about MySQL, Very easy question, but really breaked my brain for some time.
i have a table called "logs", That have "date" thing, That is INT(11) of Timestamp, So, it use timestamp actual for it.
i gonna make a script that execute a SQL command each minute, That Check ALL rows, if "date" have more/equal than 6 hours, i tired so much, and nothing for help.
Some commands i used and won't worked.
DELETE FROM logs WHERE date < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR));
DELETE FROM logs WHERE date < NOW() - INTERVAL 6 HOUR;
Won't help, So, i asking here if you can help me, Thanks.
You can do something like that :
DELETE FROM logs
WHERE FROM_UNIXTIME(date) < UNIX_TIMESTAMP(NOW() - INTERVAL 6 HOUR);
The date "thing" is called a column. The column has a specific datatype. The question indicates that the column is datatype INT(11). And in that column is stored unix-style 32-bit integer number of seconds since 1970-01-01 UTC.
If that's all true, then the first query form is appropriate. The expression on the right side (of the less than comparison) returns an integer number of seconds.
As a demonstration, consider this expression:
SELECT UNIX_TIMESTAMP( NOW() + INTERVAL -6 HOUR ) ==> 1528450555
or, the way the original is written
SELECT UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR))
returns an equivalent result.
The second query can be evaluated, but the automatic conversion from DATETIME to numeric will return us an integer value like 20180608153555 (i.e. yyyymmddhhmmss), not number of seconds since the beginning of the epoch.
Consider a demonstration, DATETIME dataytpe evaluated in numeric context:
SELECT NOW() + INTERVAL -6 HOUR + 0 ==> 20180608153600
If we use that expression, compare that to an INT(11) column, and delete all rows that have an INT(11) column less than that value, it's going to delete every row in the table that has a non-NULL value in that column.
Your date column must be of Type TIMESTAMP and not INT in order to be able compare timestamps with each other properly, or you can write:
DELETE FROM logs WHERE FROM_UNIXTIME(date) < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 6 HOUR));
I have a column in my database which holds an expire time being inserted with NOW() + INTERVAL 30 MINUTE;
I need to be able to pull out minutes remaining from that column. I have no idea where to start.
Thanks in advance.
SELECT TIMESTAMPDIFF(MINUTE,NOW(),column1) AS minutes_remaining FROM table1;
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_timestampdiff
Note that the order of the arguments is extremely counterintuitive... to get a positive number as a result, the larger (later) datetime value is the last argument. If the second argument is >= the third, the result will be <= 0.
Is there a way I can make MySQL return 1 instead of 0 for SELECT NOW() = '2016-10-10' without casting (CAST('2016-10-10' AS DATE)) or converting to date (DATE('2016-10-10')).
My real case scenario is a comparison between a DATE and a DATETIME column. I want to JOIN on those columns, but that's possible only if I can make MySQL compare only the date, ignoring the time.
I can't do the cast/convert because that is very expensive ( Slow query performance left joining a view ).
It's not the '2016-10-10' string that you need to cast (since it is a valid date literal), but NOW().
NOW() returns your current timestamp, with hours, minutes and seconds. While '2016-10-10' is interpreted as '2016-10-10 00:00:00'. Which, presumably is not equal to the current time.
So
SELECT DATE(NOW()) = '2016-10-10'
UPD:
I can make MySQL compare only the date, ignoring the time.
For the comparison coldate = coldatetime you can compare on range, like:
coldate <= coldatetime AND coldate + INTERVAL 1 DAY > coldatetime
Depending on your actual case it may or may not be beneficial.
I need to return all the entries in a MySQL database from the last hour. The database has a column named time that has epoch values in.
This bit of psuedo code is what I want to be able to achieve but am not sure how to do this in MySQL. In another language I'd check to see that the epoch value of time in each row is no more than 3,600 different.
SELECT * FROM dailyltc WHERE `time` <= 1 hour
Not using functions to convert your stored epoch value enables MySQL the use of an index. Because of that I prefer the calculate the limits with UNIX_TIMESTAMP instead of converting the stored value to a DATETIME value.
SELECT
*
FROM
dailyltc
WHERE
`time` > UNIX_TIMESTAMP(NOW() - INTERVAL 1 HOUR);
Should newer values exist then you can simply add the upper bound:
SELECT
*
FROM
dailyltc
WHERE
`time` > UNIX_TIMESTAMP(NOW() - INTERVAL 1 HOUR)
AND
`time` <= UNIX_TIMESTAMP(NOW());
I am trying to create a query that will limit insertion into a table based on the last time the poster sent data to the table.
For example if you posted data to the table then you are locked out of the system for another 10 hours. Here is what I came up with so far. But I get nowhere with the actual results on the data. Any help?
SELECT DATE( `date` )
FROM tablename
WHERE DATE( CURDATE( ) ) < CURDATE( ) - INTERVAL 1002
DAY
LIMIT 0 , 30
This will return a single post from the last 10 hours, if it exists:
SELECT *
FROM tablename
WHERE `date` >= NOW() - INTERVAL 10 HOUR
LIMIT 1
I'm assuming date is declared as DATETIME, since actual DATE does not contain the time part and hence is only day-accurate.
If date is an integer UNIX timestamp, use this:
SELECT *
FROM tablename
WHERE `date` >= UNIX_TIMESTAMP(NOW() - INTERVAL 10 HOUR)
LIMIT 1
There are a number of ways you could do this. Perhaps if you have a user settings table you could simply add a "last_insert" field, and store the timestamp as an integer value- that would be a super simple way to do it- you could check the current timestamp vs user_settings.last_insert and voila!
I suppose you could use datetime too. Whatever floats the boat.
First of all, you need a DATETIME column and not a DATE column. Assuming that tablename.date is a DATETIME column, then 10 hours before right now is CURRENT_TIMESTAMP - INTERVAL 10 HOUR.
First of all create a Time (TIMESTAMP DEFAULT CURRENT_TIMESTAMP) columnt in your table. It will be automatically set to current date on row insert
Then check:
SELECT COUNT(*) FROM Table WHERE Time > NOW() - INTERVAL 10 HOUR
If its 1 or more - block
You must compare the time last post was put with current time, not current time with current time :|