How do I subtract 30 days from the current datetime in mysql?
SELECT * FROM table
WHERE exec_datetime BETWEEN DATEDIFF(NOW() - 30 days) AND NOW();
SELECT * FROM table
WHERE exec_datetime BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW();
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
To anyone who doesn't want to use DATE_SUB, use CURRENT_DATE:
SELECT CURRENT_DATE - INTERVAL 30 DAY
MySQL subtract days from now:
select now(), now() - interval 1 day
Prints:
2014-10-08 09:00:56 2014-10-07 09:00:56
Other Interval Temporal Expression Unit arguments:
https://dev.mysql.com/doc/refman/5.5/en/expressions.html#temporal-intervals
select now() - interval 1 microsecond
select now() - interval 1 second
select now() - interval 1 minute
select now() - interval 1 hour
select now() - interval 1 day
select now() - interval 1 week
select now() - interval 1 month
select now() - interval 1 year
Let's not use NOW() as you're losing any query caching or optimization because the query is different every time. See the list of functions you should not use in the MySQL documentation.
In the code below, let's assume this table is growing with time. New stuff is added and you want to show just the stuff in the last 30 days. This is the most common case.
Note that the date has been added as a string. It is better to add the date in this way, from your calling code, than to use the NOW() function as it kills your caching.
SELECT * FROM table WHERE exec_datetime >= DATE_SUB('2012-06-12', INTERVAL 30 DAY);
You can use BETWEEN if you really just want stuff from this very second to 30 days before this very second, but that's not a common use case in my experience, so I hope the simplified query can serve you well.
You can also use
select CURDATE()-INTERVAL 30 DAY
SELECT date_format(current_date - INTERVAL 50 DAY,'%d-%b-%Y')
You can format by using date format in SQL.
If you only need the date and not the time use:
select*from table where exec_datetime
between subdate(curdate(), 30)and curdate();
Since curdate() omits the time component, it's potentially faster than now() and more "semantically correct" in cases where you're only interested in the date.
Also, subdate()'s 2-arity overload is potentially faster than using interval.
interval is meant to be for cases when you need a non-day component.
another way
SELECT COUNT(*) FROM tbl_debug WHERE TO_DAYS(`when`) < TO_DAYS(NOW())-30 ;
Related
I have a table called barcode_log, and these are all the datas from the table.
And now if I run this query
SELECT * FROM `barcode_log` WHERE barcode_log.assign_time BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY) AND CURRENT_DATE;
I get this result
But it should return all the rows as all the data is within this month only. And assign_time field is stored as datetime. Any idea what i am doing wrong??
You are ignoring the time part (hh:mm:ss).
If the end day is set to the end timestamp of the current date then you can get the data of current day's too.
BETWEEN is inclusive
SELECT
*
FROM
`barcode_log`
WHERE
barcode_log.assign_time BETWEEN DATE_SUB(
CURRENT_DATE,
INTERVAL 30 DAY
)
AND TIMESTAMP(CONCAT(CURDATE(),' ','23:59:59'));
While the accepted answer works, there is a simpler solution. Just take the date part of the datetime column:
SELECT
*
FROM
`barcode_log`
WHERE
DATE(barcode_log.assign_time)
BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY) AND CURRENT_DATE;
There is another way around: CAST() on barcode_log.assign_time field.
SELECT *
FROM `barcode_log`
WHERE CAST(barcode_log.assign_time AS DATE)
BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 30 DAY) AND CURRENT_DATE;
This excludes time from comparison and works fine for your purpose.
Here is my problem, I want to fetch next 30 days records from the table. I have a field in my table. For ex: In my table I have resource_date, In this column I have many records from 2013-02-05 to 2015-10-10. Say, If I logged into the website today(Today's Date is- 16/01/2015, It should fetch record for next 15 days and so on). How to do this? Thanks in advance
One way to do it
SELECT *
FROM table1
WHERE resource_date >= CURDATE() + INTERVAL 1 DAY -- skip today
AND resource_date < CURDATE() + INTERVAL 17 DAY -- 15 days starting tomorrow
Here is a SQLFiddle demo
In MySQL, you can use the NOW() function to get the current DATETIME, and the INTERVAL keyword to get intervals of time.
So, to get the records where resource_date is within the next 30 days, you would use:
SELECT *
FROM `my_table_name`
WHERE `resource_date` >= NOW()
AND `resource_date` < NOW() + INTERVAL 1 MONTH
;
In practice, you should rarely use SELECT *, and you should consider adding a LIMIT to this query to prevent your application from returning a result set that is "too large".
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html
...
WHERE
'resource_date'> NOW() AND
'resource_date'< DATE_ADD(NOW(), INTERVAL 31 DAY);
Careful I think now() does minutes and hours so you miss a portion of a day.
WHERE resource_date >= CURDATE() AND resource_date <= DATE_ADD(CURDATE(), interval 15 DAY)
I need to check for entries made in the last "x" days (example 30 days) and cannot get the query to work. This is what I am using:
SELECT CAL_OWNER,
CAL_TITLE,
FROM_UNIXTIME (CAL_CREATED, "%m-%d-%y") AS CREATED,
FROM_UNIXTIME (RANGE_START, "%Y-%m-%d") AS DATE2BESEEN,
CASE CAL_REFERRAL_TYPE
WHEN 1 THEN 'NoReferral'
WHEN 2 THEN 'CareyGuide'
WHEN 3 THEN 'Education'
WHEN 4 THEN 'Employment'
WHEN 5 THEN 'Housing'
WHEN 6 THEN 'Medical'
ELSE 'NA'
END
AS REFERRALS
FROM EGW_CAL
WHERE CAL_CREATED BETWEEN (NOW () - '30 day') AND NOW ()
ORDER BY REFERRALS ASC;
If I comment out the "WHERE range_start ... line the query runs fine, but pulls all data
However, if I run the complete query, it does not error, but there are no results (I have 4 entries in column cal_created in the last 3 weeks).
If some one can help I'd really appreciate it
Try using INTERVAL and either NOW() or CURDATE()..
WHERE FROM_UNIXTIME (CAL_CREATED,'%Y-%m-%d') BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE()
curdate is just the date portion of the day
if you want to include the time use NOW()
WHERE FROM_UNIXTIME (CAL_CREATED,'%Y-%m-%d') BETWEEN NOW() - INTERVAL 30 DAY AND NOW()
you could also make a new date to use the between with
WHERE FROM_UNIXTIME (CAL_CREATED,'%Y-%m-%d') BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW()
SOURCE: http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html
NOTE: the dates need to be formatted correctly in order for it to work
FULL QUERY:
SELECT
CAL_OWNER,
CAL_TITLE,
FROM_UNIXTIME (CAL_CREATED, '%m-%d-%y') AS CREATED_AT,
FROM_UNIXTIME (RANGE_START, '%Y-%m-%d') AS DATE2BESEEN,
CASE CAL_REFERRAL_TYPE
WHEN 1 THEN 'NoReferral'
WHEN 2 THEN 'CareyGuide'
WHEN 3 THEN 'Education'
WHEN 4 THEN 'Employment'
WHEN 5 THEN 'Housing'
WHEN 6 THEN 'Medical'
ELSE 'NA'
END AS REFERRALS
FROM EGW_CAL
WHERE FROM_UNIXTIME(CAL_CREATED,'%Y-%m-%d') BETWEEN (NOW() - INTERVAL 30 DAY) AND NOW()
ORDER BY REFERRALS ASC;
CAL_CREATED is a UNIX timestamp,
NOW() will return a MySQL timestamp.
They don't mix automatically. So use
WHERE CAL_CREATED
BETWEEN UNIX_TIMESTAMP(NOW() - INTERVAL 30 DAY) AND UNIX_TIMESTAMP(NOW());
Note:
I wouldn't recommend to go the other way
WHERE FROM_UNIXTIME(CAL_CREATED) BETWEEN ...
because MySQL can't use an index in this case.
The correct where clause uses internval:
WHERE CAL_CREATED BETWEEN NOW() - interval 30 day AND NOW()
The use of single quotes is reminiscent of Postgres. In MySQL, it ends up treating the value of now() as an integer. And it subtracts the string value "30 days" from it.
When now() is treated as an integer, it also has hours, minutes, and seconds. So you are really subtracting something like 30 seconds. Here is the documentation on now().
Is there a way in a MySQL statement to order records (through a date stamp) by >= NOW() -1 so all records from the day before today to the future are selected?
Judging by the documentation for date/time functions, you should be able to do something like:
SELECT * FROM FOO
WHERE MY_DATE_FIELD >= NOW() - INTERVAL 1 DAY
Be aware that the result may be slightly different than you expect.
NOW() returns a DATETIME.
And INTERVAL works as named, e.g. INTERVAL 1 DAY = 24 hours.
So if your script is cron'd to run at 03:00, it will miss the first three hours of records from the 'oldest' day.
To get the whole day use CURDATE() - INTERVAL 1 DAY. This will get back to the beginning of the previous day regardless of when the script is run.
Didn't see any answers correctly using DATE_ADD or DATE_SUB:
Subtract 1 day from NOW()
...WHERE DATE_FIELD >= DATE_SUB(NOW(), INTERVAL 1 DAY)
Add 1 day from NOW()
...WHERE DATE_FIELD >= DATE_ADD(NOW(), INTERVAL 1 DAY)
You're almost there: it's NOW() - INTERVAL 1 DAY
Sure you can:
SELECT * FROM table
WHERE DateStamp > DATE_ADD(NOW(), INTERVAL -1 DAY)
when search field is timestamp and you want find records from 0 hours yesterday and 0 hour today use construction
MY_DATE_TIME_FIELD between makedate(year(now()), date_format(now(),'%j')-1) and makedate(year(now()), date_format(now(),'%j'))
instead
now() - interval 1 day
I want to get first day of every corresponding month of current year. For example, if user selects '2010-06-15', query demands to run from '2010-06-01' instead of '2010-06-15'.
Please help me how to calculate first day from selected date. Currently, I am trying to get desirable using following mysql select query:
Select
DAYOFMONTH(hrm_attendanceregister.Date) >=
DAYOFMONTH(
DATE_SUB('2010-07-17', INTERVAL - DAYOFMONTH('2010-07-17') + 1 DAY
)
FROM
hrm_attendanceregister;
Thanks
Is this what you are looking for:
select CAST(DATE_FORMAT(NOW() ,'%Y-%m-01') as DATE);
You can use the LAST_DAY function provided by MySQL to retrieve the last day of any month, that's easy:
SELECT LAST_DAY('2010-06-15');
Will return:
2010-06-30
Unfortunately, MySQL does not provide any FIRST_DAY function to retrieve the first day of a month (not sure why). But given the last day, you can add a day and subtract a month to get the first day. Thus you can define a custom function:
DELIMITER ;;
CREATE FUNCTION FIRST_DAY(day DATE)
RETURNS DATE DETERMINISTIC
BEGIN
RETURN ADDDATE(LAST_DAY(SUBDATE(day, INTERVAL 1 MONTH)), 1);
END;;
DELIMITER ;
That way:
SELECT FIRST_DAY('2010-06-15');
Will return:
2010-06-01
There is actually a straightforward solution since the first day of the month is simply today - (day_of_month_in_today - 1):
select now() - interval (day(now())-1) day
Contrast that with the other methods which are extremely roundabout and indirect.
Also, since we are not interested in the time component, curdate() is a better (and faster) function than now(). We can also take advantage of subdate()'s 2-arity overload since that is more performant than using interval. So a better solution is:
select subdate(curdate(), (day(curdate())-1))
This is old but this might be helpful for new human web crawlers XD
For the first day of the current month you can use:
SELECT LAST_DAY(NOW() - INTERVAL 1 MONTH) + INTERVAL 1 DAY;
You can use EXTRACT to get the date parts you want:
EXTRACT( YEAR_MONTH FROM DATE('2011-09-28') )
-- 201109
This works well for grouping.
You can use DATE_FORMAT() function in order to get the first day of any date field.
SELECT DATE_FORMAT(CURDATE(),'%Y-%m-01') as FIRST_DAY_CURRENT_MONTH
FROM dual;
Change Curdate() with any other Date field like:
SELECT DATE_FORMAT(purchase_date,'%Y-%m-01') AS FIRST_DAY_SALES_MONTH
FROM Company.Sales;
Then, using your own question:
SELECT *
FROM
hrm_attendanceregister
WHERE
hrm_attendanceregister.Date) >=
DATE_FORMAT(CURDATE(),'%Y-%m-01')
You can change CURDATE() with any other given date.
There are many ways to calculate the first day of a month, and the following are the performance in my computer (you may try this on your own computer)
And the winner is LAST_DAY(#D - interval 1 month) + interval 1 day
set #D=curdate();
select BENCHMARK(100000000, subdate(#D, (day(#D)-1))); -- 33 seconds
SELECT BENCHMARK(100000000, #D - INTERVAL (day(#D) - 1) DAY); -- 33 seconds
SELECT BENCHMARK(100000000, cast(DATE_FORMAT(#D, '%Y-%m-01') as date)); -- 29 seconds
SELECT BENCHMARK(100000000, LAST_DAY(#D - interval 1 month) + interval 1 day); -- 26 seconds
I'm surprised no one has proposed something akin to this (I do not know how performant it is):
CONCAT_WS('-', YEAR(CURDATE()), MONTH(CURDATE()), '1')
Additional date operations could be performed to remove formatting, if necessary
use date_format method and check just month & year
select * from table_name where date_format(date_column, "%Y-%m")="2010-06"
SELECT LAST_DAY(date) as last_date, DATE_FORMAT(date,'%Y-%m-01') AS fisrt_date FROM table_name
date=your column name
The solutions that use last_day() and then add/subtract a month and a day are not interchangeable.
Example:
date_sub(date_add(last_day(curdate()), interval 1 day), interval 3 month)
always works for any supplied number of months you want to go back
date_add(date_sub(last_day(now()), interval 3 month), interval 1 day)
will fail in some cases, for instance if your current month has 30 days and the month you're subtracting back to (and then adding a day) has 31.
date_add(subdate(curdate(), interval day(?) day), interval 1 day)
change the ? for the corresponding date
This works fine for me.
date(SUBDATE("Added Time", INTERVAL (day("Added Time") -1) day))
** replace "Added Time" with column name
Use Cases:
If you want to reset all date fields except Month and Year.
If you want to retain the column format as "date". (not as "text" or "number")
Slow (17s):
SELECT BENCHMARK(100000000, current_date - INTERVAL (day(current_date) - 1) DAY);
SELECT BENCHMARK(100000000, cast(DATE_FORMAT(current_date, '%Y-%m-01') as date));
If you don't need a date type this is faster:
Fast (6s):
SELECT BENCHMARK(100000000, DATE_FORMAT(CURDATE(), '%Y-%m-01'));
SELECT BENCHMARK(100000000, DATE_FORMAT(current_date, '%Y-%m-01'));
select big.* from
(select #date := '2010-06-15')var
straight_join
(select * from your_table where date_column >= concat(year(#date),'-',month(#date),'-01'))big;
This will not create a full table scan.