Timestampdiff excluding some hours and weekend mysql [duplicate] - mysql

I have a field of time Timestamp in my MySQL database which is mapped to a DATE datatype in my bean. Now I want a query by which I can fetch all records in the database for which the difference between the current timestamp and the one stored in the database is > 20 minutes.
How can I do it?
What i want is:
SELECT * FROM MyTab T WHERE T.runTime - now > 20 minutes
Are there any MySQL functions for this, or any way to do this in SQL?

If you have MySql version above 5.6 you could use TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2) something like
select * from MyTab T where
TIMESTAMPDIFF(MINUTE,T.runTime,NOW()) > 20

MySql version >=5.6
I am using below code for today and database date.
TIMESTAMPDIFF(MINUTE,T.runTime,NOW()) > 20
According to the documentation, the first argument can be any of the following:
MICROSECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR

ROUND(time_to_sec((TIMEDIFF(NOW(), "2015-06-10 20:15:00"))) / 60);

Try this one:
select * from MyTab T where date_add(T.runTime, INTERVAL 20 MINUTE) < NOW()
NOTE: this should work if you're using MySQL DateTime format. If you're using Unix Timestamp (integer), then it would be even easier:
select * from MyTab T where UNIX_TIMESTAMP() - T.runTime > 20*60
UNIX_TIMESTAMP() function returns you current unix timestamp.

You can try this:
SELECT * FROM MyTab T WHERE CURRENT_TIMESTAMP() > T.runTime + INTERVAL 20 MINUTE;
The CURRENT_TIMESTAMP() is a function and returns the current date and time. This function works From MySQL 4.0

If you have MySql version prior than 5.6 you don't have TIMESTAMPDIFF. So,I wrote my own MySql function to do this. Accets %i or %m for minutes and %h for hours. You can extend it.
Example of usage:
SELECT MYTSDIFF('2001-01-01 10:44:32', '2001-01-01 09:50:00', '%h')
Here goes the function. Enjoy:
DROP FUNCTION IF EXISTS MYTSDIFF;
DELIMITER $$
CREATE FUNCTION `MYTSDIFF`( date1 timestamp, date2 timestamp, fmt varchar(20))
returns varchar(20) DETERMINISTIC
BEGIN
declare secs smallint(2);
declare mins smallint(2);
declare hours int;
declare total real default 0;
declare str_total varchar(20);
if date1 > DATE_ADD( date2, interval 30 day) then
return '999999.999'; /* OUT OF RANGE TIMEDIFF */
end if;
select cast( time_format( timediff(date1, date2), '%s') as signed) into secs;
select cast( time_format( timediff(date1, date2), '%i') as signed) into mins;
select cast( time_format( timediff(date1, date2), '%H') as signed) into hours;
set total = hours * 3600 + mins * 60 + secs;
set fmt = LOWER( fmt);
if fmt = '%m' or fmt = '%i' then
set total = total / 60;
elseif fmt = '%h' then
set total = total / 3600;
else
/* Do nothing, %s is the default: */
set total = total + 0;
end if;
select cast( total as char(20)) into str_total;
return str_total;
END$$
DELIMITER ;

Related

SQL Server - calculate elapsed time between two datetime stamps in HH:MM:SS format

I have a SQL Server table that has a "Time" column. The table is a log table the houses status messages and timestamps for each message. The log table is inserted into via a batch file. There is an ID column that groups rows together. Each time the batch file runs it initializes the ID and writes records. What I need to do is get the elapsed time from the first record in an ID set to the last record of the same ID set. I started toying with select Max(Time) - Min(Time) from logTable where id = but couldn't figure out how to format it correctly. I need it in HH:MM:SS.
SQL Server doesn't support the SQL standard interval data type. Your best bet is to calculate the difference in seconds, and use a function to format the result. The native function CONVERT() might appear to work fine as long as your interval is less than 24 hours. But CONVERT() isn't a good solution for this.
create table test (
id integer not null,
ts datetime not null
);
insert into test values (1, '2012-01-01 08:00');
insert into test values (1, '2012-01-01 09:00');
insert into test values (1, '2012-01-01 08:30');
insert into test values (2, '2012-01-01 08:30');
insert into test values (2, '2012-01-01 10:30');
insert into test values (2, '2012-01-01 09:00');
insert into test values (3, '2012-01-01 09:00');
insert into test values (3, '2012-01-02 12:00');
Values were chosen in such a way that for
id = 1, elapsed time is 1 hour
id = 2, elapsed time is 2 hours, and
id = 3, elapsed time is 3 hours.
This SELECT statement includes one column that calculates seconds, and one that uses CONVERT() with subtraction.
select t.id,
min(ts) start_time,
max(ts) end_time,
datediff(second, min(ts),max(ts)) elapsed_sec,
convert(varchar, max(ts) - min(ts), 108) do_not_use
from test t
group by t.id;
ID START_TIME END_TIME ELAPSED_SEC DO_NOT_USE
1 January, 01 2012 08:00:00 January, 01 2012 09:00:00 3600 01:00:00
2 January, 01 2012 08:30:00 January, 01 2012 10:30:00 7200 02:00:00
3 January, 01 2012 09:00:00 January, 02 2012 12:00:00 97200 03:00:00
Note the misleading "03:00:00" for the 27-hour difference on id number 3.
Function to format elapsed time in SQL Server
UPDATED:
Correctly calculate a timespan in SQL Server, even if more than 24 hours:
-- Setup test data
declare #minDate datetime = '2012-12-12 20:16:47.160'
declare #maxDate datetime = '2012-12-13 15:10:12.050'
-- Get timespan in hh:mi:ss
select cast(
(cast(cast(#maxDate as float) - cast(#minDate as float) as int) * 24) /* hours over 24 */
+ datepart(hh, #maxDate - #minDate) /* hours */
as varchar(10))
+ ':' + right('0' + cast(datepart(mi, #maxDate - #minDate) as varchar(2)), 2) /* minutes */
+ ':' + right('0' + cast(datepart(ss, #maxDate - #minDate) as varchar(2)), 2) /* seconds */
-- Returns 18:53:24
Edge cases that show inaccuracy are especially welcome!
DECLARE #EndTime AS DATETIME, #StartTime AS DATETIME
SELECT #StartTime = '2013-03-08 08:00:00', #EndTime = '2013-03-08 08:30:00'
SELECT CAST(#EndTime - #StartTime AS TIME)
Result: 00:30:00.0000000
Format result as you see fit.
The best and simple way:
Convert(varchar, {EndTime} - {StartTime}, 108)
Just like Anri noted.
Use the DATEDIFF to return value in milliseconds, seconds, minutes, hours, ...
DATEDIFF(interval, date1, date2)
interval REQUIRED - The time/date part to return. Can be one of the following values:
year, yyyy, yy = Year
quarter, qq, q = Quarter
month, mm, m = month
dayofyear = Day of the year
day, dy, y = Day
week, ww, wk = Week
weekday, dw, w = Weekday
hour, hh = hour
minute, mi, n = Minute
second, ss, s = Second
millisecond, ms = Millisecond
date1, date2 REQUIRED - The two dates to calculate the difference between
select convert(varchar, Max(Time) - Min(Time) , 108) from logTable where id=...
See if this helps. I can set variables for Elapsed Days, Hours, Minutes, Seconds.
You can format this to your liking or include in a user defined function.
Note: Don't use DateDiff(hh,#Date1,#Date2). It is not reliable! It rounds in unpredictable ways
Given two dates...
(Sample Dates: two days, three hours, 10 minutes, 30 seconds difference)
declare #Date1 datetime = '2013-03-08 08:00:00'
declare #Date2 datetime = '2013-03-10 11:10:30'
declare #Days decimal
declare #Hours decimal
declare #Minutes decimal
declare #Seconds decimal
select #Days = DATEDIFF(ss,#Date1,#Date2)/60/60/24 --Days
declare #RemainderDate as datetime = #Date2 - #Days
select #Hours = datediff(ss, #Date1, #RemainderDate)/60/60 --Hours
set #RemainderDate = #RemainderDate - (#Hours/24.0)
select #Minutes = datediff(ss, #Date1, #RemainderDate)/60 --Minutes
set #RemainderDate = #RemainderDate - (#Minutes/24.0/60)
select #Seconds = DATEDIFF(SS, #Date1, #RemainderDate)
select #Days as ElapsedDays, #Hours as ElapsedHours, #Minutes as ElapsedMinutes, #Seconds as ElapsedSeconds
Hope this helps you in getting the exact time between two time stamps
Create PROC TimeDurationbetween2times(#iTime as time,#oTime as time)
As
Begin
DECLARE #Dh int, #Dm int, #Ds int ,#Im int, #Om int, #Is int,#Os int
SET #Im=DATEPART(MI,#iTime)
SET #Om=DATEPART(MI,#oTime)
SET #Is=DATEPART(SS,#iTime)
SET #Os=DATEPART(SS,#oTime)
SET #Dh=DATEDIFF(hh,#iTime,#oTime)
SET #Dm = DATEDIFF(mi,#iTime,#oTime)
SET #Ds = DATEDIFF(ss,#iTime,#oTime)
DECLARE #HH as int, #MI as int, #SS as int
if(#Im>#Om)
begin
SET #Dh=#Dh-1
end
if(#Is>#Os)
begin
SET #Dm=#Dm-1
end
SET #HH = #Dh
SET #MI = #Dm-(60*#HH)
SET #SS = #Ds-(60*#Dm)
DECLARE #hrsWkd as varchar(8)
SET #hrsWkd = cast(#HH as char(2))+':'+cast(#MI as char(2))+':'+cast(#SS as char(2))
select #hrsWkd as TimeDuration
End

Mysql insert random datetime in a given datetime range

With SQL , Can I insert random datetime values in a column giving a range?
For example, given a range of 2010-04-30 14:53:27 to 2012-04-30 14:53:27
I'm getting confused with the range part. as i will have just done this
INSERT INTO `sometable` VALUES (RND (DATETIME()))
Here is an example that should help:
INSERT INTO `sometable` VALUES(
FROM_UNIXTIME(
UNIX_TIMESTAMP('2010-04-30 14:53:27') + FLOOR(0 + (RAND() * 63072000))
)
)
It uses the date 2010-04-30 14:53:27 as the base, converts that to a Unix timestamp, and adds a random number of seconds from 0 to +2 years to the base date and converts it back to a DATETIME.
It should be pretty close but over longer time periods leap years and other adjustments will throw it off.
This should work nicely:
SET #MIN = '2010-04-30 14:53:27';
SET #MAX = '2012-04-30 14:53:27';
SELECT TIMESTAMPADD(SECOND, FLOOR(RAND() * TIMESTAMPDIFF(SECOND, #MIN, #MAX)), #MIN);
TIMESTAMPDIFF is used to determine the number of seconds in the date range. Multiply this by a random number between 0-1 results in a random number between 0 and the number of seconds in the range. Adding this random number of seconds to the lower bound of the range results in a random date between the data range bounds.
This works perfectly even for leap years:
select from_unixtime(
unix_timestamp('2000-1-1') + floor(
rand() * (
unix_timestamp('2010-12-31') - unix_timestamp('2000-1-1') + 1
)
)
)
The idea is simple: Just take a random timestamp between the two timestamps, then convert it to a datetime using from_unixtime. This way you can ensure that each option has equal probability.
Easiest way out:
INSERT INTO `sometable` VALUES (SELECT timestamp('2010-04-30 14:53:27') - INTERVAL FLOOR( RAND( ) * 366) DAY);
Just try :
SELECT TIMESTAMP('2012-04-30 14:53:27')-INTERVAL RAND()*365*2 DAY INTO tbl_name;
SET #MIN = '2019-06-29 00:53:27';
SET #MAX = '2019-06-29 13:53:27';
UPDATE tablename
SET columnname = TIMESTAMPADD(SECOND, FLOOR(RAND() * TIMESTAMPDIFF(SECOND, #MIN, #MAX)), #MIN)
WHERE `columnname` = condition
This worked for me but my issue was a bit different. I had to assign certain values in a column to a random datetime.
UPDATE Tablename
SET columnName = addtime(concat_ws(' ','2018-07-25' + interval rand()*2 day
,'00:00:00'),sec_to_time(floor(0 + (rand() * 86401))))
WHERE columnName = condition;
It's an old thread but still.. In my case I needed to generate random date in format like this : 2017-01-01.
If anyone will need it I have used #drew010 solution and formatted date with DATE_FORMAT.
Here is my code :
SELECT DATE_FORMAT(FROM_UNIXTIME(UNIX_TIMESTAMP('2015-01-01') + FLOOR(0 + (RAND() * 63072000))), '%Y-%m-%d');
Use following dynamic query.
SET #MIN = NOW() - INTERVAL 2 MONTH;
SET #MAX = now();
select TIMESTAMPADD(SECOND, FLOOR(RAND() * TIMESTAMPDIFF(SECOND, #MIN, #MAX)), #MIN)
Thanks to #sapna-bhayal

How can I store a MySQL interval type?

This is what I would like to be able to do:
SET #interval_type := MONTH;
SELECT '2012-01-01' + INTERVAL 6 #interval_type;
+------------+
|'2012-06-01'|
+------------+
And of course that doesn't work and there is no "interval" data type in MySQL.
I want to be able to store an interval value and an interval type in a table so that i can have the database quickly do the math naturally without having to write a big switch statement, ala
... ELSE IF (type = 'MONTH') { SELECT #date + INTERVAL #value MONTH; } ...
Is this supported in any way in MySQL or do you have a clever hack for this?
Thanks; you rock.
This solution may come handy to somebody implementing the job queue for cron or something similar.
Let us suppose we have a reference date (DATETIME) and interval of repetition. We would like to store both values in database and get the quick comparison whether it's already time to execute and include job into execution queue or not.
The interval could be non trivial e.g. (1 YEAR 12 DAYS 12 HOUR) and is controlled by wise user (admin) so that user is not going to use values exceeding the range of regular DATETIME data type or otherwise the conversion must be implemented first. (18 MONTH -> 1 YEAR 6 MONTH).
We can use then DATETIME data type for storing both values reference date and interval. We can define stored function using:
DELIMITER $$
CREATE DEFINER=`my_db`#`%` FUNCTION `add_interval`(`source` DATETIME, `interval` DATETIME) RETURNS datetime
BEGIN
DECLARE result DATETIME;
SET result = `source`;
SET result=DATE_ADD(result, INTERVAL EXTRACT(YEAR FROM `interval`) YEAR);
SET result=DATE_ADD(result, INTERVAL EXTRACT(MONTH FROM `interval`) MONTH);
SET result=DATE_ADD(result, INTERVAL EXTRACT(DAY FROM `interval`) DAY);
SET result=DATE_ADD(result, INTERVAL EXTRACT(HOUR FROM `interval`) HOUR);
SET result=DATE_ADD(result, INTERVAL EXTRACT(MINUTE FROM `interval`) MINUTE);
SET result=DATE_ADD(result, INTERVAL EXTRACT(SECOND FROM `interval`) SECOND);
RETURN result;
END
We can then make DATETIME arithmetic using this function e.g.
// test solution
SELECT add_interval('2014-07-24 15:58:00','0001-06-00 00:00:00');
// get job from schedule table
SELECT job FROM schedule WHERE add_interval(last_execution,repetition)<NOW();
// update date of executed job
UPDATE schedule SET last_execution=add_interval(last_execution,repetition);
You can solve this problem using prepared statements, considering there is no language construct available for use. The benefit here being you get the performance and flexibility that you want; this could easily be placed in a stored procedure or function for added value:
SET #date = '2012-01-01';
SET #value = 6;
SET #type = 'MONTH';
SET #q = 'SELECT ? + INTERVAL ? ';
SET #q = CONCAT(#s, #type);
PREPARE st FROM #q;
EXECUTE st USING #date, #value;
Alternatively, depending on your database / software architecture and the type of date/time intervals you are thinking of, you could simply this problem by using a time-scale interval:
SELECT #date + INTERVAL #value SECOND
1 second - 1
1 minute - 60
1 hour - 3600
1 day - 86400 (24 hours)
1 week - 604800 (7 days)
1 month - 2419200 (4 weeks)
Here's the simplistic approach. It works reasonably fast. You can change the order of the switch statements to optimize for speed if you feel that you will be hitting some more often then others. I have not benched this against Chris Hutchinson's solution. I ran into problems trying to wrap it into a nice function because of the dynamic SQL. Anyway, for posterity, this is guaranteed to work:
CREATE FUNCTION AddInterval( date DATETIME, interval_value INT, interval_type TEXT )
RETURNS DATETIME
DETERMINISTIC
BEGIN
DECLARE newdate DATETIME;
SET newdate = date;
IF interval_type = 'YEAR' THEN
SET newdate = date + INTERVAL interval_value YEAR;
ELSEIF interval_type = 'QUARTER' THEN
SET newdate = date + INTERVAL interval_value QUARTER;
ELSEIF interval_type = 'MONTH' THEN
SET newdate = date + INTERVAL interval_value MONTH;
ELSEIF interval_type = 'WEEK' THEN
SET newdate = date + INTERVAL interval_value WEEK;
ELSEIF interval_type = 'DAY' THEN
SET newdate = date + INTERVAL interval_value DAY;
ELSEIF interval_type = 'MINUTE' THEN
SET newdate = date + INTERVAL interval_value MINUTE;
ELSEIF interval_type = 'SECOND' THEN
SET newdate = date + INTERVAL interval_value SECOND;
END IF;
RETURN newdate;
END //
It comes with this equally simplistic benchmark test:
CREATE FUNCTION `TestInterval`( numloops INT )
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE date DATETIME;
DECLARE newdate DATETIME;
DECLARE i INT;
SET i = 0;
label1: LOOP
SET date = FROM_UNIXTIME(RAND() * 2147483647);
SET newdate = AddInterval(date,1,'YEAR');
SET i = i+1;
IF i < numloops THEN
ITERATE label1;
ELSE
LEAVE label1;
END IF;
END LOOP label1;
return i;
END //

Calculating time difference between 2 dates in minutes

I have a field of time Timestamp in my MySQL database which is mapped to a DATE datatype in my bean. Now I want a query by which I can fetch all records in the database for which the difference between the current timestamp and the one stored in the database is > 20 minutes.
How can I do it?
What i want is:
SELECT * FROM MyTab T WHERE T.runTime - now > 20 minutes
Are there any MySQL functions for this, or any way to do this in SQL?
If you have MySql version above 5.6 you could use TIMESTAMPDIFF(unit,datetime_expr1,datetime_expr2) something like
select * from MyTab T where
TIMESTAMPDIFF(MINUTE,T.runTime,NOW()) > 20
MySql version >=5.6
I am using below code for today and database date.
TIMESTAMPDIFF(MINUTE,T.runTime,NOW()) > 20
According to the documentation, the first argument can be any of the following:
MICROSECOND
SECOND
MINUTE
HOUR
DAY
WEEK
MONTH
QUARTER
YEAR
ROUND(time_to_sec((TIMEDIFF(NOW(), "2015-06-10 20:15:00"))) / 60);
Try this one:
select * from MyTab T where date_add(T.runTime, INTERVAL 20 MINUTE) < NOW()
NOTE: this should work if you're using MySQL DateTime format. If you're using Unix Timestamp (integer), then it would be even easier:
select * from MyTab T where UNIX_TIMESTAMP() - T.runTime > 20*60
UNIX_TIMESTAMP() function returns you current unix timestamp.
You can try this:
SELECT * FROM MyTab T WHERE CURRENT_TIMESTAMP() > T.runTime + INTERVAL 20 MINUTE;
The CURRENT_TIMESTAMP() is a function and returns the current date and time. This function works From MySQL 4.0
If you have MySql version prior than 5.6 you don't have TIMESTAMPDIFF. So,I wrote my own MySql function to do this. Accets %i or %m for minutes and %h for hours. You can extend it.
Example of usage:
SELECT MYTSDIFF('2001-01-01 10:44:32', '2001-01-01 09:50:00', '%h')
Here goes the function. Enjoy:
DROP FUNCTION IF EXISTS MYTSDIFF;
DELIMITER $$
CREATE FUNCTION `MYTSDIFF`( date1 timestamp, date2 timestamp, fmt varchar(20))
returns varchar(20) DETERMINISTIC
BEGIN
declare secs smallint(2);
declare mins smallint(2);
declare hours int;
declare total real default 0;
declare str_total varchar(20);
if date1 > DATE_ADD( date2, interval 30 day) then
return '999999.999'; /* OUT OF RANGE TIMEDIFF */
end if;
select cast( time_format( timediff(date1, date2), '%s') as signed) into secs;
select cast( time_format( timediff(date1, date2), '%i') as signed) into mins;
select cast( time_format( timediff(date1, date2), '%H') as signed) into hours;
set total = hours * 3600 + mins * 60 + secs;
set fmt = LOWER( fmt);
if fmt = '%m' or fmt = '%i' then
set total = total / 60;
elseif fmt = '%h' then
set total = total / 3600;
else
/* Do nothing, %s is the default: */
set total = total + 0;
end if;
select cast( total as char(20)) into str_total;
return str_total;
END$$
DELIMITER ;

Difference between two dates in MySQL

How to calculate the difference between two dates, in the format YYYY-MM-DD hh: mm: ss and to get the result in seconds or milliseconds?
SELECT TIMEDIFF('2007-12-31 10:02:00','2007-12-30 12:01:01');
-- result: 22:00:59, the difference in HH:MM:SS format
SELECT TIMESTAMPDIFF(SECOND,'2007-12-30 12:01:01','2007-12-31 10:02:00');
-- result: 79259 the difference in seconds
So, you can use TIMESTAMPDIFF for your purpose.
If you are working with DATE columns (or can cast them as date columns), try DATEDIFF() and then multiply by 24 hours, 60 min, 60 secs (since DATEDIFF returns diff in days). From MySQL:
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
for example:
mysql> SELECT DATEDIFF('2007-12-31 23:59:59','2007-12-30 00:00:00') * 24*60*60
Get the date difference in days using DATEDIFF
SELECT DATEDIFF('2010-10-08 18:23:13', '2010-09-21 21:40:36') AS days;
+------+
| days |
+------+
| 17 |
+------+
OR
Refer the below link
MySql difference between two timestamps in days?
SELECT TIMESTAMPDIFF(HOUR,NOW(),'2013-05-15 10:23:23')
calculates difference in hour.(for days--> you have to define day replacing hour
SELECT DATEDIFF('2012-2-2','2012-2-1')
SELECT TO_DAYS ('2012-2-2')-TO_DAYS('2012-2-1')
select
unix_timestamp('2007-12-30 00:00:00') -
unix_timestamp('2007-11-30 00:00:00');
If you want to add where clause with DATEDIFF then it is also possible to add where clause or condition.
Take a look of following example.
select DATEDIFF(now(), '2022-08-12 17:55:51.000000') from properties p WHERE p.property_name = 'KEY';
Result : 6
SELECT TIMESTAMPDIFF(SECOND,'2018-01-19 14:17:15','2018-01-20 14:17:15');
Second approach
SELECT ( DATEDIFF('1993-02-20','1993-02-19')*( 24*60*60) )AS 'seccond';
CURRENT_TIME() --this will return current Date
DATEDIFF('','') --this function will return DAYS and in 1 day there are 24hh 60mm 60sec
Or, you could use TIMEDIFF function
mysql> SELECT TIMEDIFF('2000:01:01 00:00:00', '2000:01:01 00:00:00.000001');
'-00:00:00.000001'
mysql> SELECT TIMEDIFF('2008-12-31 23:59:59.000001' , '2008-12-30 01:01:01.000002');
'46:58:57.999999'
This function takes the difference between two dates and shows it in a date format yyyy-mm-dd. All you need is to execute the code below and then use the function. After executing you can use it like this
SELECT datedifference(date1, date2)
FROM ....
.
.
.
.
DELIMITER $$
CREATE FUNCTION datedifference(date1 DATE, date2 DATE) RETURNS DATE
NO SQL
BEGIN
DECLARE dif DATE;
IF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < 0 THEN
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(DATE_SUB(date1, INTERVAL 1 MONTH)), '-', DAY(date2))))),
'%Y-%m-%d');
ELSEIF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < DAY(LAST_DAY(DATE_SUB(date1, INTERVAL 1 MONTH))) THEN
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))),
'%Y-%m-%d');
ELSE
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))),
'%Y-%m-%d');
END IF;
RETURN dif;
END $$
DELIMITER;
select TO_CHAR(TRUNC(SYSDATE)+(to_date( '31-MAY-2012 12:25', 'DD-MON-YYYY HH24:MI')
- to_date( '31-MAY-2012 10:37', 'DD-MON-YYYY HH24:MI')),
'HH24:MI:SS') from dual
-- result : 01:48:00
OK it's not quite what the OP asked, but it's what I wanted to do :-)
This code calculate difference between two dates in yyyy MM dd format.
declare #StartDate datetime
declare #EndDate datetime
declare #years int
declare #months int
declare #days int
--NOTE: date of birth must be smaller than As on date,
--else it could produce wrong results
set #StartDate = '2013-12-30' --birthdate
set #EndDate = Getdate() --current datetime
--calculate years
select #years = datediff(year,#StartDate,#EndDate)
--calculate months if it's value is negative then it
--indicates after __ months; __ years will be complete
--To resolve this, we have taken a flag #MonthOverflow...
declare #monthOverflow int
select #monthOverflow = case when datediff(month,#StartDate,#EndDate) -
( datediff(year,#StartDate,#EndDate) * 12) <0 then -1 else 1 end
--decrease year by 1 if months are Overflowed
select #Years = case when #monthOverflow < 0 then #years-1 else #years end
select #months = datediff(month,#StartDate,#EndDate) - (#years * 12)
--as we do for month overflow criteria for days and hours
--& minutes logic will followed same way
declare #LastdayOfMonth int
select #LastdayOfMonth = datepart(d,DATEADD
(s,-1,DATEADD(mm, DATEDIFF(m,0,#EndDate)+1,0)))
select #days = case when #monthOverflow<0 and
DAY(#StartDate)> DAY(#EndDate)
then #LastdayOfMonth +
(datepart(d,#EndDate) - datepart(d,#StartDate) ) - 1
else datepart(d,#EndDate) - datepart(d,#StartDate) end
select
#Months=case when #days < 0 or DAY(#StartDate)> DAY(#EndDate) then #Months-1 else #Months end
Declare #lastdayAsOnDate int;
set #lastdayAsOnDate = datepart(d,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#EndDate),0)));
Declare #lastdayBirthdate int;
set #lastdayBirthdate = datepart(d,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#StartDate)+1,0)));
if (#Days < 0)
(
select #Days = case when( #lastdayBirthdate > #lastdayAsOnDate) then
#lastdayBirthdate + #Days
else
#lastdayAsOnDate + #Days
end
)
print convert(varchar,#years) + ' year(s), ' +
convert(varchar,#months) + ' month(s), ' +
convert(varchar,#days) + ' day(s) '
If you've a date stored in text field as string you can implement this code it will fetch the list of past number of days a week, a month or a year sorting:
SELECT * FROM `table` WHERE STR_TO_DATE(mydate, '%d/%m/%Y') < CURDATE() - INTERVAL 30 DAY AND STR_TO_DATE(date, '%d/%m/%Y') > CURDATE() - INTERVAL 60 DAY
//This is for a month
SELECT * FROM `table` WHERE STR_TO_DATE(mydate, '%d/%m/%Y') < CURDATE() - INTERVAL 7 DAY AND STR_TO_DATE(date, '%d/%m/%Y') > CURDATE() - INTERVAL 14 DAY
//This is for a week
%d%m%Y is your date format
This query display the record between the days you set there like: Below from last 7 days and Above from last 14 days so it would be your last week record to be display same concept is for month or year. Whatever value you're providing in below date like: below from 7-days so the other value would be its double as 14 days. What we are saying here get all records above from last 14 days and below from last 7 days. This is a week record you can change value to 30-60 days for a month and also for a year.
Thank You Hope it will help someone.
You would simply do this:
SELECT (end_time - start_time) FROM t; -- return in Millisecond
SELECT (end_time - start_time)/1000 FROM t; -- return in Second
Why not just
Select Sum(Date1 - Date2) from table
date1 and date2 are datetime