Retrieve rows less than a day old - mysql

I have a column date, which has a default value of CURRENT_TIMESTAMP, eg: 2011-11-16 15:34:02. Is there any way to put a condition in the mysql statement (not in php) to retrieve rows which are less than a day old? Something like:
SELECT * FROM orders where date > 24 hours ago

You can use timestampadd() to get the timestamp for 24 hours ago
SELECT * FROM orders WHERE `date` > timestampadd(hour, -24, now());
This is equivalent to
SELECT * FROM orders WHERE `date` > timestampadd(day, -1, now());

SELECT *
FROM orders
WHERE DATE(`date`) = DATE(NOW() - INTERVAL 1 DAY)
Note the backticks around date, as it's a reserved word.

yup, combine *date_sub* with interval 1 day and curdate() and maybe something else
see documentation here http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-sub

This statement returns all today's rows:
select * from orders where date_field >= CURDATE();
CURDATE() returns today's date, so searches the records starting from midnight.

You can use also the difference directly with timestampdiff function witch is similar to timestampadd.
SELECT * FROM orders WHERE TIMESTAMPDIFF(HOUR, date, NOW()) > 24;
I think this can't as optimized as using timestampadd (because it calculate the difference for each row) but it's, in my opinion, more readable and an alternative if you don't care about optimizing.

Related

Select all MySQL records in the last day that are between a time range of 7am and midnight

I have this query
SELECT * FROM `timeclock_timecard`
WHERE `clock_in_datetime` > DATE_SUB(CURDATE(), INTERVAL 1 DAY)
which can get record in the last day but I need to limit to records created after 7AM
Any help please?
SELECT * FROM `timeclock_timecard`
WHERE `clock_in_datetime` > DATE_SUB(CURDATE(), INTERVAL 1 DAY)
and hour(`clock_in_datetime`) > 7;
Added one more filter condition to check for the hour.
Your query was almost correct, because CURDATE() only gives the date you can just subtract 17 hours to get the correct result. fiddle.
SELECT * FROM `timeclock_timecard`
WHERE `clock_in_datetime` >= DATE_SUB(CURDATE(), INTERVAL 17 HOUR)
To get the entries of the current day, we can add 7 hours (CURDATE() has time 0:00).
SELECT * FROM `timeclock_timecard`
WHERE `clock_in_datetime` >= DATE_ADD(CURDATE(), INTERVAL 7 HOUR)
To get only rows from yesterday, with a time value of 7AM or later, we can add 7 hours to the expression.
If we only up until midnight of today (just rows from yesterday), we can add another condition, the datetime is less than midnight today.
For example:
SELECT t.*
FROM `timeclock_timecard` t
WHERE t.`clock_in_datetime` >= DATE(NOW()) + INTERVAL -1 DAY + INTERVAL 7 HOUR
AND t.`clock_in_datetime` < DATE(NOW())
If you want to exclude the exact 7:00:00 AM value, change the >= to just >.
FOLLOWUP
Q: What I actually want is between about 5-6am TODAY and mindnight TODAY so anytime during today that I run the report for today I will get only timeclock data from users who clocked in/out today only and not include yesterdays data.
A: The predicates are going to be of the form
WHERE t.`clock_in_datetime` >= expr1
AND t.`clock_in_datetime` < expr2
You just need to find the expressions expr1 and expr2 that return the appropriate datetime values.
Just use a simple SELECT statement to test:
SELECT DATE(NOW()) + INTERVAL 5 HOUR AS `start`
, DATE(NOW()) + INTERVAL 1 DAY AS `end`
Q: I also modified my select to take in account my datetime is in UTC and my result needs to get todays records using local timezone.
SELECT * , CONVERT_TZ( clock_in_datetime , '+00:00', '-4:00' ) FROM `timeclock_timecard`
A: Personally, I would do the timezone conversion on the exprN values, not the column values. Having predicates on bare columns allows MySQL to make effective use of an index; wrapping the columns in expressions prevents MySQL from using an index.
If the MySQL system clock is UTC, and your datetime values stored in the table are in a different timezone, yes, use the MySQL CONVERT_TZ function.
Again, using a simple SELECT statement to develop and test the expressions:
SELECT CONVERT_TZ( DATE(NOW()) + INTERVAL 5 HOUR, '+0:00', to_tz) AS `start`
, CONVERT_TZ( DATE(NOW()) + INTERVAL 1 DAY , '+0:00', to_tz) AS `end`
Where to_tz is the timezone of the values in the table.
Once you get expressions start and end returning the values you need, then use those expressions in the predicates of the query of the timecard table.

Find records with a time field in the last 24 hours

In my SQL query how do i find records in the last 24 hours?
I am using time() function for inserting into db.
I am using time-stamp the time is stored in this format.Eg 1332673046
select somefield from yourtable where timefield >= subtime(current_timestamp(), '1 00:00:00');
You can use BETWEEN
SELECT * FROM users
WHERE created_at BETWEEN '2012-03-31 00:00:00 UTC' AND '2012-03-31 23:59:59 UTC'
I am not certain if you are looking to check within the same calendar day, or as you say within the past 24 hours, so here's what I usually do for both cases:
a) For the same calendar day:
CONVERT(VARCHAR(8), myTable.myDate, 112) = CONVERT(VARCHAR(8), GETDATE(), 112)
b) For the date to be within the past 24 hours (inclusive)
DATEDIFF(hour, myTable.myDate, GETDATE()) <= 24
Simple DATE arithmetic would do,
SELECT *
FROM `table1`
WHERE `time_col` BETWEEN NOW() AND NOW()- INTERVAL 24 HOURS;
Given that you are storing dates as unix timestamps then you need UNIX_TIMESTAMP like this
SELECT
// fields you need
FROM `table`
WHERE
`date_field` BETWEEN UNIX_TIMESTAMP( DATE_SUB(NOW() INTERVAL 24 HOUR) ) AND UNIX_TIMESTAMP()
You might want to consider storing dates in MySQLs DATETIME format as it makes date calculations in MySQL much easier.

SELECT all records that are 30 days old

I need to SELECT all records that are 30 days old. I have the code below but it's not working. In updatestatus I have dates like 12/26/2011. I create a 30 day old date like
$onemonthago="01/01/2012";
$sth = $dbh->prepare(qq(
SELECT *
FROM people
WHERE STR_TO_DATE (updatestatus,'%m/%d/%y')
<= STR_TO_DATE ( "$onemonthago",'%m/%d/%Y')
) );
If the datatype of updatestatus is date:
SELECT *
FROM people
WHERE updatestatus <= '2012-01-01'
or:
SELECT *
FROM people
WHERE updatestatus <= CURRENT_DATE() - INTERVAL 1 MONTH
If the datatype is datetime or timestamp and you want to check the time part, too:
SELECT *
FROM people
WHERE updatestatus <= NOW() - INTERVAL 1 MONTH
You can put an exact datetime instead of the NOW() - INTERVAL 1 MONTH. The correct way depends on how you are storing the datetimes or timestamps (does the Perl code or MySQL creates them in the first place?).
You could also put - INTERVAL 30 DAY which yield slightly different results.
This is what I used. Very simple
$sth = $dbh->prepare(qq(SELECT * FROM people WHERE updatestatus + INTERVAL 30 DAY <= NOW() )) or die $DBI::errstr;
If the time column is in timestamp then use below query.(use from_unixtime function)
SELECT wd.* FROM `watchdog` as wd
WHERE from_unixtime(wd.timestamp) <= NOW() - INTERVAL 1 MONTH
You can try this way. In SQL, there is dateadd function and I think there should be similar function in MySQL.
select *
from Table
where str_to_date between dateadd(day,-30,getdate()) and getdate()
It retrieve records between current date and past 30 days. You need to adjust for time. If you don't count time, you need to remove timestamp.

How to get first day of every corresponding month in mysql?

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.

Select mysql query between date?

How to select data from mysql table past date to current date? For example, Select data from 1 january 2009 until current date ??
My column "datetime" is in datetime date type. Please help, thanks
Edit:
If let say i want to get day per day data from 1 january 2009, how to write the query? Use count and between function?
select * from *table_name* where *datetime_column* between '01/01/2009' and curdate()
or using >= and <= :
select * from *table_name* where *datetime_column* >= '01/01/2009' and *datetime_column* <= curdate()
All the above works, and here is another way if you just want to number of days/time back rather a entering date
select * from *table_name* where *datetime_column* BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW()
You can use now() like:
Select data from tablename where datetime >= "01-01-2009 00:00:00" and datetime <= now();
Late answer, but the accepted answer didn't work for me.
If you set both start and end dates manually (not using curdate()), make sure to specify the hours, minutes and seconds (2019-12-02 23:59:59) on the end date or you won't get any results from that day, i.e.:
This WILL include records from 2019-12-02:
SELECT *SOMEFIELDS* FROM *YOURTABLE* where *YOURDATEFIELD* between '2019-12-01' and '2019-12-02 23:59:59'
This WON'T include records from 2019-12-02:
SELECT *SOMEFIELDS* FROM *YOURTABLE* where *YOURDATEFIELD* between '2019-12-01' and '2019-12-02'