I want to know is it possible in mysql query.. when I say give me date when it is 9am.. the return answer is depends upon current time when it is 8am it give me today's date. when it is 10pm it gives me tomorrow date. how it is possible in mysql query.
You can use SUBSTRING_INDEX(CURTIME(), ':', 1) to get the hours of current time.
As I understood you want to get tomorrow date, if it is 10pm or later
Example given:
SELECT
CASE
WHEN SUBSTRING_INDEX(CURTIME(), ':', 1) >= 22
THEN DATE_ADD(CURDATE(), INTERVAL 1 DAY)
ELSE CURDATE()
END
Source: http://www-db.deis.unibo.it/courses/TW/DOCS/w3schools/sql/sql_dates.asp.html
You can get the hour value from a given datetime expression, using HOUR function. CURDATE() function is used to return the current date. You can add/subtract 'integers' to it get the date corresponding to current date +/- 'integer days' . Assuming that the time >= 10 pm returns next day:
SELECT IF(HOUR(`datetime_field`) > 22, CURDATE(), CURDATE() + 1);
You could just add 2 hours
SELECT DATE(DATE_ADD(NOW(), INTERVAL 2 HOUR));
This will then return tomorrow’s date for anytime after 10pm.
Related
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.
I am trying to check for all records that occurred last month using the following statement.
Select * from statistics
where statistics_date
BETWEEN date_format(NOW() - INTERVAL 1 MONTH, '%Y-%m-01')
AND last_day(NOW() - INTERVAL 1 MONTH )
However, the selection does not include the last day. What I want is from the first second of the month until the last second of the month.
BETWEEN is notoriously bad for date and timestamp work because it gets the end date wrong.
Here's what you need:
First, let's compute the first day of the present month. You had that exactly right.
DATE_FORMAT(NOW(),'%Y-%m-01')
Next, let's compute the first day of last month:
DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL 1 MONTH
Now, we select the records that lie in the interval.
Select *
from statistics
where statistics_date >= DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL 1 MONTH
and statistics_date < DATE_FORMAT(NOW(),'%Y-%m-01')
Do you see how the beginning of the date range is chosen with >= and the end with <? Do you see how I used the first day of the present month for the end of the date range? Those things are important, because timestamps can have days and times in them. Consider the timestamp '2013-01-31 23:58'. It happens to be after '2012-01-31' so between won't catch it.
where MONTH(statistics_date) = MONTH(NOW()) - 1
For "2012-07-12", how can I get the start of the week, i.e., "2012-07-08", and start of the month, i.e., "2012-07-01"?
First day of the month:
SELECT DATE_FORMAT('2007-07-12', '%Y-%m-01');
output: 2007-07-01
First day of the week:
SELECT DATE_SUB('2007-07-12', INTERVAL DAYOFWEEK('2007-07-12')-1 DAY);
output: 2007-07-08
MySQL reference: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
Same answer as Borophyll's, but I have changed the behavior of the first day of the month to return a date, not just a string which avoids date formatting/parsing mentioned in user151220's answer.
First day of the month:
SELECT DATE_SUB('2007-07-12', INTERVAL DAYOFMONTH('2007-07-12') - 1 DAY);
output: 2007-07-01
First day of the week:
SELECT DATE_SUB('2007-07-12', INTERVAL DAYOFWEEK('2007-07-12') - 1 DAY);
output: 2007-07-08
MySQL reference: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_date-add
For those who need Monday as the first day of the week:
SELECT DATE_SUB('2007-07-12', INTERVAL WEEKDAY('2007-07-12') DAY);
output: 2007-07-09
This relies on the WEEKDAY function, which starts with Monday instead of DAYOFWEEK, which starts with Sunday.
The DATE_FORMAT reply from Borophyll is very good, but gives a string rather than a date. So can't be compared easily.
If you need to use this as a comparison to a date field, use str_to_date to reverse it back to date rather than string.
select x from y where date >= str_to_date( DATE_FORMAT(now()-interval 12 month,'Y-%m-01'), '%Y-%m-%d')
If you are (say) looking at 12 months sales figures, but you want to always start off from the 1st of a month.
This will work if you want to just code it and forget about it, it will use datetime now and always return MTD results-
where date_completed between date_sub(date(now()), INTERVAL dayofmonth(now()) -1 day) and now()
Suppose I have 2011-01-03 and I want to get the first of the week, which is sunday, which is 2011-01-02, how do I go about doing that?
The reason is I have this query:
select
YEAR(date_entered) as year,
date(date_entered) as week, <-------This is what I want to change to select the first day of the week.
SUM(1) as total_ncrs,
SUM(case when orgin = picked_up_at then 1 else 0 end) as ncrs_caught_at_station
from sugarcrm2.ncr_ncr
where
sugarcrm2.ncr_ncr.date_entered > date('2011-01-01')
and orgin in(
'Silkscreen',
'Brake',
'Assembly',
'Welding',
'Machining',
'2000W Laser',
'Paint Booth 1',
'Paint Prep',
'Packaging',
'PEM',
'Deburr',
'Laser ',
'Paint Booth 2',
'Toolpath'
)
and date_entered is not null
and orgin is not null
AND(grading = 'Minor' or grading = 'Major')
and week(date_entered) > week(current_timestamp) -20
group by year, week(date_entered)
order by year asc, week asc
And yes, I realize that origin is spelled wrong but it was here before I was so I can't correct it as too many internal apps reference it.
So, I am grouping by weeks but I want this to populate my chart, so I can't have all the beginning of weeks looking like different dates. How do I fix this?
If the week starts on Sunday do this:
DATE_ADD(mydate, INTERVAL(1-DAYOFWEEK(mydate)) DAY)
If the week starts on Monday do this:
DATE_ADD(mydate, INTERVAL(-WEEKDAY(mydate)) DAY);
more info
If you need to handle weeks which start on Mondays, you could also do it that way. First define a custom FIRST_DAY_OF_WEEK function:
DELIMITER ;;
CREATE FUNCTION FIRST_DAY_OF_WEEK(day DATE)
RETURNS DATE DETERMINISTIC
BEGIN
RETURN SUBDATE(day, WEEKDAY(day));
END;;
DELIMITER ;
And then you could do:
SELECT FIRST_DAY_OF_WEEK('2011-01-03');
For your information, MySQL provides two different functions to retrieve the first day of a week. There is DAYOFWEEK:
Returns the weekday index for date (1 = Sunday, 2 = Monday, …, 7 = Saturday). These index values correspond to the ODBC standard.
And WEEKDAY:
Returns the weekday index for date (0 = Monday, 1 = Tuesday, … 6 = Sunday).
If week starts on Monday
SELECT SUBDATE(mydate, weekday(mydate));
If week starts on Sunday
SELECT SUBDATE(mydate, dayofweek(mydate) - 1);
Example:
SELECT SUBDATE('2018-04-11', weekday('2018-04-11'));
2018-04-09
SELECT SUBDATE('2018-04-11', dayofweek('2018-04-11') - 1);
2018-04-08
Week starts day from sunday then get First date of the Week and Last date of week
SELECT
DATE("2019-03-31" + INTERVAL (1 - DAYOFWEEK("2019-03-31")) DAY) as start_date,
DATE("2019-03-31" + INTERVAL (7 - DAYOFWEEK("2019-03-31")) DAY) as end_date
Week starts day from Monday then get First date of the Week and Last date of week
SELECT
DATE("2019-03-31" + INTERVAL ( - WEEKDAY("2019-03-31")) DAY) as start_date,
DATE("2019-03-31" + INTERVAL (6 - WEEKDAY("2019-03-31")) DAY) as end_date
select '2011-01-03' - INTERVAL (WEEKDAY('2011-01-03')+1) DAY;
returns the date of the first day of week. You may look into it.
This is a much simpler approach than writing a function to determine the first day of a week.
Some variants would be such as
SELECT DATE_ADD((SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE())+1)DAY),INTERVAL 7 DAY) (for the ending date of a query, such as between "beginning date" and "ending date").
SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE())+1) DAY (for the beginning date of a query).
This will return all values for the current week. An example query would be as follows:
SELECT b.foo FROM bar b
WHERE b.datefield BETWEEN
(SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE())+1) DAY)
AND (SELECT DATE_ADD((SELECT CURDATE() - INTERVAL (WEEKDAY(CURDATE())+1)DAY),INTERVAL 7 DAY))
This works form me
Just make sure both dates in the below query are the same...
SELECT ('2017-10-07' - INTERVAL WEEKDAY('2017-10-07') Day) As `mondaythisweek`
This query returns: 2017-10-02 which is a monday,
But if your first day is sunday, then just subtract a day from the result of this and wallah!
If the week starts on Monday do this:
DATE_SUB(mydate, INTERVAL WEEKDAY(mydate) DAY)
SELECT MIN(DATE*given_date*) FROM *table_name*
This will return when the week started at for any given date.
Keep the good work going!
I need mySQL timestamp for start of current week or any given date, if week starts with monday?
I'm trying something like:
SELECT UNIX_TIMESTAMP(CONCAT( DATE_SUB(CURDATE(), INTERVAL WEEKDAY(DATE_SUB(CURDATE(), INTERVAL 7 DAY)) DAY), ' 00:00:00')) as start
Monday has a dayofweek index=2. DAYOFWEEK($date) gives the index of the day (1-7, Sun-Sat). So, you need to add or subtract days from your $date's index to change it to 2.
e.g.
SELECT UNIX_TIMESTAMP(
CASE WHEN DAYOFWEEK($date)>=2
THEN DATE_SUB($date, INTERVAL (DAYOFWEEK($date)-2) DAYS)
ELSE DATE_ADD($date INTERVAL 1 DAY)
END
);
I think I've got the syntax right on this, but check CASE and date and time functions.