Mysql time range query using extract - mysql

I'm trying to get an mysql query similar to date_trunc in psql.
Unfortunate Mysql do not have date_trunc function and I found I can use extract instead in Mysql.
What I want to do is write a script which i will run let say 10 minutes past each hour but I want to only select data from begin of an hour till end of this hour.
For example I will run script 12:10 and I want to display data from 11:00:00 till 11:59:59.
In PSQL query would look like that:
SELECT *
FROM data
WHERE time > ( date_trunc('hour',now()) - interval '1 hour' )
AND time <= ( date_trunc('hour',now()) ) ORDER BY time;
I was trying to use extract in similar fashion but I have no rows returned or error :/
Query below returns for example some narrowed data but it's like 2 hours each day from day one when database was started not last hour only:
SELECT *
FROM data
WHERE extract(hour from cr_date) between extract(hour from now()) - interval 1 hour)
AND extract(hour from now())
ORDER BY cr_date;
Any ideas how this can be achieved? or what I'm doing wrong in this query?

Hour is only an integer, so it's finding any matches between , for example, 9 and 10, regardless of the date.
I would recommend
select * FROM data
where cr_date >= date(now()) + INTERVAL hour(now())-1 HOUR
and cr_date <= date(now()) + INTERVAL hour(now()) HOUR
date(now()) returns midnight, and hour(now()) returns the number of hours since midnight
so, at 11:10 am, it should result in a results between midnight + 10 hours (10 am) and midnight + 11 hours (11 am)

Related

Select records between a date in d-mY format and 1rst of next month, plus 1 day in Mysql

I need to select all data from a table 'followup' between followup_date and first of next month (including 1rst of next month). The format of my date in DB (obtained from an API) is d-m-Y.
The follow-up date for example is: 18-07-2020.
I have the following query:
SELECT * from followup
WHERE DATEDIFF(STR_TO_DATE(`followup_date`,'%d-%m-%Y'), DATE_FORMAT(CURDATE() + INTERVAL 1 MONTH,'%Y-%m-01'))- 1 < 0 ;
I am getting -15 days as difference and getting records correctly, including 1rst. Is the query correct and efficient and will it work correctly for all months.
Requesting suggestions from experts for improvements, if any.
You should convert your followup_date column to a DATE type. You can then make your query sargable by removing the function calls on followup_date and simply comparing it with the target date:
SELECT * from followup
WHERE `followup_date` <= DATE_FORMAT(CURDATE() + INTERVAL 1 MONTH,'%Y-%m-01')
I suspect adding one day to LAST_DAY(CURDATE()) might be more efficient:
SELECT * from followup
WHERE `followup_date` <= LAST_DAY(CURDATE()) + INTERVAL 1 DAY
Demo on SQLFiddle

How can I use DATEDIFF() to return rows where it has been more than 24 hours since it was added

I have table with column called date_added stored as datetime in MySQL.
I want to return rows where it has been 24 hours or more since it was added to the database.
I'm using the following query. However, it doesn't return what I want it to return.
SELECT * FROM campaign WHERE datediff(date_added,NOW())>=1
Here's what date_added in the Database looks like: 2017-08-15 00:48:31
You can do it this way
//This code is for SQL
SELECT *, DATEDIFF(HOUR,date_added,NOW()) AS Hours
FROM campaign WHERE DATEDIFF(HOUR,date_added,NOW()) >=24
As you can see i made the diff by hour
UPDATED
Try this one below.
SELECT * FROM campaign
WHERE HOUR(TIMEDIFF(DATE_FORMAT(date_added, "%Y-%m-%d %H:%i:%s"), DATE_FORMAT(NOW(), "%Y-%m-%d %H:%i:%s"))) >= 24
I used TimeDiff and used dateformat
and made it to hour.
You can also used this query
SELECT * FROM campaign WHERE TIMESTAMPDIFF(HOUR, date_added, NOW()) >= 24
Don't use any kind of "diff". Either of these will do match rows 'added' more than 24 hours ago.
WHERE date_added < NOW() - INTERVAL 1 DAY
WHERE date_added < NOW() - INTERVAL 24 HOUR
Since CURDATE() is midnight this morning, this will catch anything done anytime yesterday or today:
WHERE date_added < CURDATE() - INTERVAL 1 DAY

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.

Data from current date to 30 days after current days

Why this query is not working
SELECT * FROM history WHERE DATE(date) < CURDATE() + 30
I am trying to get the data from 30 days but my query is not working.Why
What does +30 mean? Days? Years? Months? Hours? You need to use (the proper syntax) a format MySQL understands:
SELECT * FROM history WHERE DATE(date) < CURDATE() + INTERVAL 30 DAY
To get the data from today on to 30 days after current day, you've got to set an upper and an lower limit, so use:
SELECT * FROM history WHERE
date >= CURDATE()
AND
date < CURDATE() + INTERVAL 31 DAY
Please note that by not using a function on your date column you won't prohibit MySQL to use an index on this column.
The lower limit should be obvious, the upper limit means that you've got the complete day that's 30 days later than today. If you use + INTERVAL 30 DAY instead this last day is excluded from the result.
Because you're not using the right construct, try:
SELECT * FROM history WHERE DATE_ADD(date, INTERVAL 30 DAY);

getting number of hours until the next event

I've got a table with this data:
[ID] [event_name] [last_event]
1 stats 2011-01-01 01:47:32
last_event is a timestamp. The event occurs every 48 hours (it's a cron job). I'd like to show my users the number of hours until the event executes again.
So far I've got:
SELECT (lastFinish + INTERVAL 48 HOUR) FROM `cron_status`
which gives me the exact time and date of the next occurence: 2011-01-03 01:47:32. So I figured if I subtracted the current datetime...
SELECT ((lastFinish + INTERVAL 48 HOUR) - SYSDATE()) FROM `cron_status`
which (I think?) gives me the difference in unix time: 1980015. But if I divide that by 3600 to convert the seconds to hours...
SELECT (((lastFinish + INTERVAL 48 HOUR) - SYSDATE())/3600) FROM `cron_status`
I get numbers an order of magnitude too high: 549.99.
Where am I going wrong? The target is returning the number of hours until the next execution.
Thank you!
The result can be obtained directly, using the timediff() MySQL function:
SELECT timediff(lastFinish + INTERVAL 48 HOUR, now()) FROM cron_status;
should display the time as hh:mm:ss. Assuming lastFinish is a datetime.
In order to get the answer in hours instead,
SELECT timestampdiff(HOUR, now(), lastFinish + INTERVAL 48 HOUR) FROM cron_status;
Note that timediff does arg1 - arg2 while timestampdiff does arg2 - arg1.