MySQL Timestamp Difference - mysql

I have a table with column timestam which stores a timestamp with this format: "2012-12-10 21:24:30"
I am looking for a SQL Query that takes the current timestamp and subtracts it with the one in the column and gives the difference in this format:
"3 Hours and 2 mins Remaining"
Looking for a MySQL Query that does that.

use TIMESTAMPDIFF
TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2)
where unit argument, which should be one of the following values:
MICROSECOND (microseconds), SECOND, MINUTE, HOUR, DAY, WEEK, MONTH,
QUARTER, or YEAR.
my approach : set unit as SECOND and then use SEC_TO_TIME
SELECT SEC_TO_TIME(TIMESTAMPDIFF(SECOND,`table`.`time_column`,CURRENT_TIMESTAMP()))
// will return in hh:mm:ii format
update
Return yes if HourDifference are less than 48 hours? otherwise no
SELECT IF(TIMESTAMPDIFF(HOUR,`time_column`,CURRENT_TIMESTAMP())< 48 ,'yes','no')

Assume your table name is 'testtable'
Table create query is given below
CREATE TABLE `testtable` (
`id` INT(2) NOT NULL AUTO_INCREMENT,
`period` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
Insert some data to test my query. Query to insert some data is given below
INSERT INTO `testtable` (`id`, `period`) VALUES
(1, '2012-12-10 17:21:09'),
(2, '2012-11-06 18:21:12'),
(3, '2012-12-06 18:21:18'),
(4, '2012-12-06 19:21:24'),
(5, '2012-12-06 18:21:27');
Now execute following query to get your answer
SELECT *,
CONCAT(HOUR(difftime), ' hours ', MINUTE(difftime), ' Minutes ',
SECOND(difftime), ' seconds remaining') AS timetaken
FROM (SELECT *,
SEC_TO_TIME(UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(
ttable.period)) AS
diffTime
FROM testtable ttable) AS temptable1
Output is given below
The column 'timetaken' will display answer.

Related

select data by unix timestamp

Below are the table I've created and its records:
CREATE TABLE students (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
gender TEXT NOT NULL,
created_at datetime
);
INSERT INTO students VALUES (1, 'Ryan', 'M', '2012-11-03 00:00:00');
INSERT INTO students VALUES (2, 'Joanna', 'F', '2013-11-03 00:00:00');
To fetch the records by time, I use the following SQL statement:
SELECT * FROM students WHERE created_at > 1620489600000;
and both records can be returned, which confuses me because 1620489600000 (Sat May 08 2021 16:00:00 GMT+0000) should be a timestamp way later than the create_at fields of both records.
Indeed I know this can also be achieved by specifying a time formatted as 2012-11-03 00:00:00, but I just wonder:
whether we can effectively query a datetime column in where clause with unix timestamp?
if not, why does the above select statement return both records?
To compare two different data types MySQL automatically converts one of them to the other. In this case it tries to make numbers of the dates. What is the result? See here
The date gets converted to
20121103000000
which is bigger than
1620489600000
So the result in your WHERE clause is true and returns all records.
If you need to go from a Unix Timestamp you could use this:
WHERE created_at > FROM_UNIXTIME(1620489600000 / 1000)
Notice that I divided by 1000 because Unix time has to be in seconds and not milli seconds.

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

How to get the amount of extra hours registered for each day reported in MySQL stored procedure

Having an attendance report which displays the entrance, lunch time exit, lunch time entrance and final exit for each user, I need to display the extra hours worked counting only the time after 20:30 and limited to 21:30.
i.e.
if a worker reports its exit around 20:10 it shouldn't count as extra time.
if a worker reports its exit around 21:00 it should count as extra time.
if a worker reports its exit after 21:30 it should only count as extra time until 21:30.
Having the following table:
CREATE TABLE `tblassistance` (
`Entrance` datetime NOT NULL,
`LunchExit` datetime DEFAULT NULL,
`LunchEntrance` datetime DEFAULT NULL,
`DayExit` datetime DEFAULT NULL,
`UserID` int(11) NOT NULL);
INSERT INTO tblassistance(Entrance, LunchExit, LunchEntrance, DayExit, UserID) VALUES ('2019-01-05 14:30:00','2019-01-05 15:30:00','2019-01-05 16:30:00','2019-01-05 21:30:00', '1');
INSERT INTO tblassistance(Entrance, LunchExit, LunchEntrance, DayExit, UserID) VALUES ('2019-01-05 14:30:00','2019-01-05 15:30:00','2019-01-05 16:30:00','2019-01-05 21:36:00', '2');
INSERT INTO tblassistance(Entrance, LunchExit, LunchEntrance, DayExit, UserID) VALUES ('2019-01-05 14:30:00','2019-01-05 15:30:00','2019-01-05 16:30:00','2019-01-05 21:00:00', '3');
INSERT INTO tblassistance(Entrance, LunchExit, LunchEntrance, DayExit, UserID) VALUES ('2019-01-05 14:30:00','2019-01-05 15:30:00','2019-01-05 16:30:00','2019-01-05 20:10:00', '4');
The report needs to display the extra time for each user counting from 20:30 of each day limited to 21:30.
So far I've managed to (try to) sketch the following query:
(SELECT TIMEDIFF(DATE(tblassistance.DayExit) = CURDATE() && tblassistance.DayExit> (SELECT CONCAT(CURDATE(), ' 21:30:00'))) GROUP BY tblassistance.userID, tblassistance.entrance
The original report is in a stored procedure format, which only receives an initial and final date, and also reports the number of days and other parameters unrelated to the present issue. If it's needed in order to solve the present issue (getting the TIMEDIFF() amount of extra time reported for a date) I can give further details.
Try this query:
SELECT
UserID,
GREATEST(
"00:00:00",
TIMEDIFF(
LEAST( DayExit, DATE_FORMAT( DayExit, "%Y-%m-%d 21:30:00" ) ) ,
DATE_FORMAT( DayExit, "%Y-%m-%d 20:30:00" )
)
)
FROM `tblassistance`

How to select data rows from MySQL if i have few date rows separately?

i have
day column,
month column,
year column,
content1 column,
content2 column,
example:
day 12
month 6
year 2015
What query i need to select all rows between 10/03/2014 and 03/04/2015 for example? The problem is that i have days and month separately. I need to extract all content1 and content2 regarding two dates.
In MySQL this query will work
SELECT content1,content2 FROM the_table
WHERE STR_TO_DATE(CONCAT(month, '/', day, '/', year), '%m/%d/%Y') BETWEEN '10/03/2014' AND '03/04/2015';
Hope that helps you out
Try this:
SELECT
*
FROM
my_table
HAVING
CONVERT(CONCAT(year, '-', month, '-', day), DATE) BETWEEN '2014-10-03' AND '2015-03-04';(Year||' '||Day||' '||Month, 'YYYY DD MM') BETWEEN date1 AND date2
Use a Date or Datetime and spare yourself of the grief that would otherwise follow
drop table theGuy;
create table theGuy
(
id int not null auto_increment primary key,
fullName varchar(60) not null,
birthDate date not null
);
insert theGuy (fullName,birthDate) values ('Kim Smithers','2002-3-1'),('John Doe','2014-4-5');
select * from theGuy where birthDate>='2000-1-1' and birthDate<='2007-12-31';
select * from theGuy where birthDate between '2000-1-1' and '2007-12-31';
select *,birthDate+interval 45 DAY as BirthCertAvail from theGuy;
select *,datediff(curdate(),birthDate) as DaysAlive from theGuy;
You might find the built-in routines adequate, such as intervals, without having to rewrite them. ;)

Get all 24 hours in a sql query

my question is how can I select all 24 hours in a day as data in a select?
There is a more polished way to do that:
select 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
from dual
My target db is Mysql, but a sql-standard solution is appreciated!
MySQL doesn't have recursive functionality, so you're left with using the NUMBERS table trick -
Create a table that only holds incrementing numbers - easy to do using an auto_increment:
DROP TABLE IF EXISTS `example`.`numbers`;
CREATE TABLE `example`.`numbers` (
`id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Populate the table using:
INSERT INTO NUMBERS
(id)
VALUES
(NULL)
...for as many values as you need. In this case, the INSERT statement needs to be run at least 25 times.
Use DATE_ADD to construct a list of hours, increasing based on the NUMBERS.id value:
SELECT x.dt
FROM (SELECT TIME(DATE_ADD('2010-01-01', INTERVAL (n.id - 1) HOUR)) AS dt
FROM numbers n
WHERE DATE_ADD('2010-01-01', INTERVAL (n.id - 1) HOUR) <= '2010-01-02' ) x
Why Numbers, not Dates?
Simple - dates can be generated based on the number, like in the example I provided. It also means using a single table, vs say one per data type.
SELECT * from dual WHERE field BETWEEN 0 AND 24