I am running a query that gets today's activity as at now() and compares it to activity at the same time for the past 5 days.
select count(*) ,date(timestamp) date , now() now
from activitylog
where timestamp>date_add(now(), INTERVAL -5 DAY) and
hour(timestamp) <=hour(now())
group by date(timestamp)
order by date(timestamp) desc;
Is there a way of doing it more efficiently than the above way?
As written, the query will return the day's activity up to the current hour for the current day and the previous 4 days, plus the current hour's activity only for five days ago - to make it include the whole day to the current hour for the fifth day, change the where clause to:
where timestamp>date(date_add(now(), INTERVAL -5 DAY)) and
hour(timestamp) <=hour(now())
Apart from this, the only issue I can think of is to check that there is an index on the timestamp column. Otherwise, it appears to be in its optimum form.
Related
I am having problem in finding some records in MySql using the following query
select
dletterdate,
days,
date_add(dletterdate,interval days day) as added ,
now() as todaysdate, datediff(now(),date_add(dletterdate,interval days day)) as difference
from mandereports
Actually i want to display only those records whose difference is less than zero. This is screenshot of the output:
You can use WHERE clause.
select
dletterdate,
days,
date_add(dletterdate,interval days day) as added ,
now() as todaysdate, datediff(now(),date_add(dletterdate,interval days day)) as difference
from mandereports
where difference < 0
Hope this helps
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.
This query is selecting rows applied last 30 days:
SELECT `amount` FROM `mg_inputs` WHERE `amount`<0 AND `product`='144' AND DATE(firstedit) BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE()
How about queries selecting rows applied last 30 days, but 1 month ago (between: today-30days and today-60days)? Same question goes for "2 months ago". Nothing is working for me at all (SQL is returning errors).
One important thing to note here is that not all months are 30 days, so instead of using INTERVAL DAY use INTERVAL MONTH.
Next, you don't need to use the subtraction sign for dates, you can use the DATE_SUB() function which will do what you need.
Last, keeping those things in mind, you can use the BETWEEN operator to check for rows within a date range. So, for example, if you want all rows from one month ago, try this:
SELECT *
FROM myTable
WHERE dateColumn BETWEEN DATE_SUB(CURDATE(), INTERVAL 2 MONTH) AND DATE_SUB(CURDATE(), INTERVAL 1 MONTH);
You should note that for the BETWEEN operator to work properly, the older date must appear first. Here is an SQL Fiddle example that demonstrates that.
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 have a table as below
user
---------
id
created_on: DATETIME
I want to get all the users where the time difference between the current time and created_on time must be greater than 30 minutes. (created_on date time - current date time) > 30 minutes
How to do this in mysql.
You can take advantage of the MySQL function TIMESTAMPDIFF to calculate it for you:
SELECT id,
created_on
FROM user
WHERE TIMESTAMPDIFF(MINUTE, created_on, NOW()) > 30
Live DEMO.
SELECT * FROM user WHERE created_on < (NOW() - INTERVAL 30 MINUTE)
In addition to example by Prix,
You can also use date_sub or date_add on the column with interval option.
select * from user
where created_on >= date_sub( now(), interval 30 minute);
The difference when used with date_add shall be negative, e.g. interval -30 minute.
There are other date and time functions with which you can get the same result.
Refer to:
MySQL: Date and Time Functions