I have a column in my table that is set as curret_timestamp, so the mysql database automatically puts the timestamp in when a record is created.
I need to get all records for the current day. At the moment I have my WHERE like this:
WHERE r.ts > DATE_SUB(NOW(), INTERVAL 1 DAY)
But this is giving me the last 24hrs. Which means that in the morning it still shows yesterday. So how can I say 'Give me all r.ts from 5am this morning?'
If you want all records with a timestamp from the current day later than 5am use
SELECT * FROM t
WHERE r.ts > CONCAT(CURDATE(), ' 05:00:00')
If you want all records with a timestamps since the last time it was 5am use
SELECT * FROM t
WHERE r.ts > CONCAT(IF(CURTIME() < '05:00:00', DATE_SUB(CURDATE(), INTERVAL 1 DAY), CURDATE()), ' 05:00:00')
The queries result only in different results from 00:00:00 - 04:59:59, so the first and easier alternative should be used, if there are no queries in that time.
You can try this-
select * from t
WHERE
DATE_FORMAT(t.ts,'%Y:%m:%d') = DATE_FORMAT(now(), '%Y:%m:%d') AND
DATE_FORMAT(t.ts,'%H:%i:%s') > STR_TO_DATE('05:00:00', '%H:%i:%s');
Explaination: The first condition check for current date and match it. And than it check for time it must be greater than morning 5 AM.
SQLFiddle
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.
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.
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);
I'm looking for a way of selecting rows based on:
Current week (S-S)
Previous week (S-S)
The problem I'm having is selecting specifically from Sunday-Sunday.
At the moment I'm using:
SELECT SUM(time)
FROM `time`
WHERE `projectid` = '$pid' && created > DATE_SUB(NOW(), INTERVAL 1 WEEK)
Any help would be great, thanks!
MySQL does have a WEEK function that you can use:
SELECT SUM(time)
FROM `time`
WHERE
`projectid` = '$pid'
AND created > NOW() - INTERVAL 2 WEEK
AND WEEK(created) IN (WEEK(NOW()), WEEK(NOW() - INTERVAL 1 WEEK))
Notes
The first condition (created > NOW() - INTERVAL 2 WEEK) is needed to get all the data of the current and previous weeks first and then restrict for the two weeks you are interested in. Otherwise, if you had enough data, you would get the aggregation of all data of the corresponding weeks of every year in your table. It also has the added benefit of allowing the query to use an index on that field.
You also need to use "WEEK(NOW() - INTERVAL 1 WEEK)" due to the first week of the year. Otherwise, WEEK(NOW()) - 1 would have sufficed
I have data stored in a mySQL database and I want to retrieve the rows that have been inserted between now and the beginning of the current hour: not in the last hour, since the start of the hour. For example, at 9:16 I want the rows from 9:00 until now. My time is stored in datatime format. How can I do this?
The query below selects all rows that are between the current hour and current time. So if current time is 10:11 it will select all rows between 10:00 and 10:11 within current date.
SELECT *
FROM Test
WHERE mytime BETWEEN DATE_FORMAT(NOW(), '%Y-%m-%d %H:00:00')
AND DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s')
I Tested it and worked.
The first thing that comes to mind is:
select *
from t
where date(now() ) = date(t.timeval) and
hour(now() ) = hour(t.timeval)
I made the assumption that you don't have future records in the data. If so, then this comes to mind:
select *
from t
where date(now() ) = date(t.timeval) and
hour(now() ) = hour(t.timeval) and
timeval < now()
SELECT * FROM times WHERE t >= DATE_FORMAT(NOW(),'%Y-%m-%d %H:00:00');