MySQL select dependant on time of day - mysql

I want to select from a MySQL table and filter depending on the time of day:
if now > 10am select uploaded date where created date is today
if now < 10am select uploaded date where created date is yesterday

I think you must use Cron jobs for this.
Then, your sql will look like that:
WHERE tbl.TimeCreated = DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
assuming this format of the field: DateTime(YYYY-MM-DD HH:MM:SS)

This should do what you need.
SELECT
`uploaded_date`
FROM
`table`
WHERE
`created_date` = CASE WHEN CURTIME() > 100000
THEN CURDATE()
ELSE CURDATE() - INTERVAL 1 DAY
END
You can see a similar example in this fiddle which should return a single row of "AM" in the morning, "Noon" at noon, and "PM" in the afternoon (and 2 empty result sets).

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.

Get all `Timestamp` from 5am today

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

SQL Query to restrict return dates to current month

I am trying to restrict my returned data to only those points that have start and end dates in the current month - active projects. It is behaving problematically because today is the last day of the month. I believe that tomorrow will be a problem as well (no June data included in the sample).
Here is my data set (Table 1):
Project User Effort Start_Date End_Date
------- ------- ------ -------- --------
Traffic Control DOMAIN\john.smith 0.1 5/1/2013 5/31/2013
Turboencabulator Analysis DOMAIN\mark.webber 0 5/1/2013 5/31/2013
Widget Calibration DOMAIN\mark.webber 0 5/1/2013 5/31/2013
Gizmo Creation DOMAIN\steve.green 0.1 5/1/2013 5/31/2013
Advanced Toolmaking DOMAIN\steve.green 0.6 5/1/2013 5/31/2013
Diesel Engine Diagnostics DOMAIN\steve.green 0.05 5/1/2013 5/31/2013
Cold Fusion Reactor Creation DOMAIN\steve.green 0.3 5/1/2013 5/31/2013
When using the following query today I get no returned results:
SELECT * FROM dbo.table1
WHERE Start_Date <= (getdate()) AND End_Date >= (getdate())
ORDER BY User, Start_Date
Yesterday it was returning just fine. I have data for June as well (not displayed in my sample) but I need to modify my statement such that it will reliably return data for the current month throughout the entirety of the month.
Answer - Correct WHERE statement (from comments in answer below):
WHERE (Month(Start_Date) <= Month((getdate())) AND Month(End_Date) >= Month((getdate()))) AND (YEAR(Start_Date) <= YEAR((getdate())) AND YEAR(End_Date) >= YEAR((getdate())))
Use TSQL Month function:
SELECT * FROM dbo.table1
WHERE Month(Start_Date) = Month(getdate()) AND Month(End_Date) = Month(getdate())
ORDER BY User, Start_Date
Just consolidate your WHERE statement into something like:
DATEDIFF(m, DATEFIELD, GETDATE()) = 0
The following query can take advantage of indexes since it does not perform calculations on every row. In addition, it returns as "active" any project that is active at any time during the month, e.g. a project that starts in the last week of the month and ends several months hence. And it's easy to test and modify since it separates the date arithmetic from the query.
declare #Today as Date = GetDate()
declare #StartOfMonth as Date = DateAdd( day, 1 - Day( #Today ), #Today )
declare #EndOfMonth as Date = DateAdd( day, -1, DateAdd( month, 1, #StartOfMonth ) )
select #Today as [Today], #StartOfMonth as [StartOfMonth], #EndOfMonth as [EndOfMonth]
select *
from Table1
where Start_Date <= #EndOfMonth and End_Date >= #StartOfMonth
You should try using convert(date, GetDate())GetDate().
Dates are represented as ticks, meaning smaller than seconds. if you compare GetDate() (which is 2013-05-31 11:09:45:1024 for exmaple, unsure about millisecond precision in mssql), it will always be greater than 2013-05-31, because of the hours/minutes/seconds. Your 2 choices are to compare YOURDATE >= Start_Date AND End_Date + 1 > YOURDATE, or YOURDATE >= Start_Date AND End_Date >= convert(date, YOURDATE)
First options asks for it to be stricly less than the morrow of the end date (so basically the very end of that day), second one asks for it to be within the same day as the end date, ignoring ticks. Both yields the exact same result, one of them is probably more performant, however I can't help on that side of things.
EDIT : or you can use the other two's answer, except that it will only work if you always use monthly periods. and in that case it would be simpler to redesign your database to only have a 1-12 field representing the month.
In MySql, I use something similar to update data within x number of days, perhaps something like:
start_date <= DATE_SUB(curdate(), INTERVAL 10 DAY);
Just change 10 to whatever number of days you need.
Try this for MySQL
select date(date_joined),count(*) from users where MONTH(date_joined)=MONTH(now()) and YEAR(date_joined)=YEAR(now()) group by date(date_joined);

SQL Query for reservation dates that break a month end?

I'm using a custom PHP function to produce a visual calendar for a single month that blocks out dates based on a table that contains an start date, and an duration - For example:
...This is produced by data saying that the table should be blocked out for 4 days from the 14th, and 7 days from the 27th.
The query looks something like this:
SELECT GROUP_CONCAT(DATE_FORMAT(start_date,'%d'),':', event_duration) AS info
FROM events
WHERE YEAR(start_date = '2012'
AND MONTH(start_date) = '07'
ORDER BY start_date
(You could safely ignore the group concat and return the data as individual rows, that doesn't really matter).
I'm looking for a modification to the query that would block out dates at the start of the month IF an event starts in the previous month, but its length takes it into the following.
For instance - in the above example, the event on the 27th is actually scheduled to last 7 days in the database, so if I ran the query for MONTH(start_date) = '08' I'd like to say the first two dates blocked out, which they wouldn't currently be, because the start date that would block it out is not in the month being selected.
I'm fairly sure there's a subquery or something in there to grab the rows, but I just can't think of it. Any takers?
EDIT
The answer from Salman below pointed me in the directon I wanted to go, and I came up with this as a way of getting carryovers from the previous month to show as '1st' of the month with the number of remaining days:
SELECT IF(MONTH(start_date) < '08', '2012-08-01', start_date) AS starter,
IF(MONTH(start_date) < '08', duration - DATEDIFF('2012-08-01',start_date), duration) AS duration
FROM EVENTS
WHERE YEAR(start_date) = '2012'
AND (MONTH(start_date) = '08' OR MONTH(start_date + INTERVAL duration DAY) = '08')
Obviously a lot of variables there to replace in PHP, so maybe there's an even better way?
Original Answer:
Assuming that the month in question is 2012-07, you need this query:
SELECT column1, column2, columnN
FROM `events`
WHERE `start_date` <= '2012-07-01'
AND `start_date` + INTERVAL `duration` DAY > '2012-07-01'
ORDER BY start_date
Revised Answer:
Apparently you need a query that checks for overlapping (or conflicting) dates. The example dates are 2012-07-01 through 2012-08-01 and the query is:
SELECT *
FROM events
WHERE '2012-08-01' > start_date
AND start_date + INTERVAL duration DAY > '2012-07-01'
ORDER BY start_date
To constrain the start date and interval, you can use SELECT ... CASE statement:
SELECT
CASE
WHEN start_date < '2012-07-01' THEN '2012-07-01'
ELSE start_date
END AS start_date_copy,
CASE
WHEN start_date < '2012-07-01' THEN duration - DATEDIFF('2012-07-01', start_date)
ELSE duration
END AS duration_copy,
FROM ...
The answer I was looking for, thanks to the other contributor for pointing me in the right direction and enabling me to solve it!
This is based on $yyyy and $mm coming from PHP (in my case, into a function call), and selecting individual rows rather than grouping:
SELECT start_date, duration
FROM reservations
WHERE YEAR(start_date) = '".$yyyy."'
AND MONTH(start_date) = '".$mm."'
UNION
SELECT '".$yyyy."-".$mm."-01',
duration - DATEDIFF('".$yyyy."-".$mm."-01',start_date)
FROM reservations
WHERE YEAR(start_date) = '".$yyyy."'
AND MONTH(start_date) < '".$mm."'
AND MONTH(start_date + INTERVAL duration DAY) = '".$mm."'
ORDER BY start_date

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'