How to design table structure for Operating Hours - mysql

Problem #1:
How can the table be designed in MySQL in efficient way to structure
1) Store Opening Time,
2) Break Time and
3) Closing Time in a day
For an instance, On Sunday: Opening Time: 7:00AM, Closing Time: 5:00PM, Break Time Start: 1:00PM, Break Time End: 2:30PM.
Problem #2:
How to define the query to search that table for all Stores that are being Opened/Closed between the given range.
For an instance, If user tries to filter the stores for Opening between 9:00AM and 12:00AM. How can I apply query for this filter since it might be possible the Break Time or Closing Time could be within that timeframe.
store_id day open_time break_start break_end close_time
1 mon 7:00AM 1:00PM 2:30PM 5:00PM
1 tue 7:00AM 1:00PM 2:30PM 5:00PM
1 wed 7:00AM 1:00PM 2:30PM 5:00PM
1 thu 7:00AM 1:00PM 2:30PM 5:00PM
1 fri 7:00AM 1:00PM 2:30PM 5:00PM
1 sat Closed
1 sun Closed
Something similar to this. If the user uses criteria: Open Time between: 8:00AM to 2:00PM; to search the store then He must be able to see all the stores that are opened during that timeframe. This timeframe must also include with store open_time. That is, based on criteria provided, the store is Open at 7:00AM, 8:00AM and 9:00AM and until 2:PM.

Better to create three different columns, since you want to query between
Opening time , closing time or break time
create table store_timing
(
store_id int, -- from store table
Opening_Time datetime,
break_time datetime,
closing_time datetime
)
Query :
select *
from store_timing
where Opening_Time<= 'Opening_Time'
and closing_time <= 'closing_time'

Related

How do I create a DATE that starts and ends at 0600 every day

My database collects data and stores in a database with date stamp (in fact two columns one date and another time. now my requirement is to have another column called date (just two digits of date ranging from 01 to 31) but the date should be changing at 06:00 hours instead of 00:00. so for example if date is 14th of Dec and time is 05:30, the DATE should return as 13 and should change to 14 only after 06:00 on 14th Dec. similarly if the date is 15th Dec and time is 03:00 , it should show 14 and not 15
please help in building a sql syntax to achieve the same.
Thanks in advance
Manjunath S

Compare datetime using CASE

I have a database table of start time and end time of an event that takes place in the real world.
I believe the data type of the start time and end time is of the datetime/timestamp type inside the db. It is definitely not a string.
The records in the table look something like the below:
id | start time | end time
1 | 2020-08-18 10:00:00 | 2020-08-18 11:00:00
2 | 2020-08-18 19:00:00 | 2020-08-18 20:00:00
3 | 2020-08-18 05:00:00 | 2020-08-18 06:00:00
Right now, I am trying to do something like a classification to see if the event take place before / during/ after 'office/work hours'.
The column SamplingStart is the start time of the event.
The column SamplingEnd is the end time of the event.
Below is a portion of my query written in MySQL:
CASE
WHEN DATE_FORMAT(b01.SamplingStart, '%Y-%m-%d') = DATE_FORMAT(b01.SamplingEnd, '%Y-%m-%d') AND b01.Speed * 3.6 >= 5 THEN
CASE
WHEN TIME(b01.SamplingStart) >= '08:00:00' AND TIME(b01.SamplingEnd) <= '17:00:00' THEN "During office hours"
WHEN TIME(b01.SamplingStart) >= '17:01:00' AND TIME(b01.SamplingEnd) <= '23:59:00' THEN "After office hours"
WHEN TIME(b01.SamplingStart) >= '00:01:00' AND TIME(b01.SamplingEnd) <= '07:59:00' THEN "Before office hours"
END
WHEN b01.Speed = 0 THEN "No Usage"
END AS VUsage
My thought process was like this. I first determine if the start time and end time are of the same day and don't care about the time part of the datetime column. If they are of the same day. Then I just have to compare the hours to see if they are before/after office hours within the same day.
The way the code above written seemingly fulfills most of my records in the database table and I can get the string representation for most of my rows in the table.
But something wrong occurs for some specific time ranges. When the start time is for example 17 Aug 2020 11pm and the end time for that record is 18 Aug 2020 8:05am then the result of my query returns a blank for that particular row.
I guess this is because 17 Aug 11pm is the 'after hours', however the end time is 18 Aug 8:05am which is the 'before hours' range. I am guessing that because there is conflict, that is why the result for the particular row in the table is blank.
I was thinking the way to overcome this is to think that if the start time and end time are of a different day. i.e. 17 aug vs 18 aug. I can 'assume' that this is after hours. This feels slightly wrong. I am not 100% sure.
I also have a feeling that they may be other time frames which my CASE statement inside my SQL code cannot properly catch and resulting in a blank classification.
I feel that I may have missed out something and wanted to know if there a better/cleverer way for this situation?
Thank you!
I think you could safely say
WHEN TIME(b01.SamplingStart) >= '08:00:00' AND TIME(b01.SamplingEnd) <= '17:00:00' THEN "During office hours"
WHEN TIME(b01.SamplingStart) >= '17:00:01' THEN "After office hours"
WHEN TIME(b01.SamplingStart) >= '00:00:01' AND TIME(b01.SamplingEnd) <= '07:59:59' THEN "Before office hours"
If all you want to know is when the event started to signify After or Before office hours
Note I also made the time more precise so you dont miss any events

MYSQL: Inserting time period OR time/moment

I want to build a little calendar system for my website.
When the user creates an appointment he can choose between a time period (like 3rd march to 7th march) and a concrete day with time/moment (like 3rd march 2016 11:00).
I want to insert this into the mysql database.
Values for inserting a time period:
date1: 3rd march 2016
date2: 7th march 2016
Values for inserting a concrete day with time:
datetime: 3rd march 2016 11:00
Now the question I stuck on: How should the table look like?
I thought on sth like this (only the columns):
id | appointment | date1 | date2 | datetime1
And when the user inserts a time period the datetime-field would be empty. But is this the way to go?
One way would be
id
appointment
startdate
starttime (empty if it is an entry for a whole day)
enddate (empty if it is a single entry without a period)
endtime (empty if it is an entry for a whole day)

MySQL store time conditions

I am currently working on a platform where I would like to offer some rentals.
I want to store all possible rental types in the database, so I do not need to take care of logic in code.
Basically I want to offer following rental-times:
1 day
7 days
5 days / need to be weekdays ( which is monday to
friday )
2 days / weekend ( needs to be saturday till sunday )
1 month / which will be from e.g. 14 of some month till 13th of following month
For the time of days I thought of storing data in minutes, this is easy to figure out.
If there is a weekday condition I thought of using the DAYOFWEEK Indexes, so I could define for 5 days, the first day of rental needs to have index 2 which is Monday, for weekend I could define that the day of rental needs to have index 6, which is Saturday.
rental_type_id | rental_time_in_minutes | rental_label | rental_start_day_indexes
1 day would be like
1 | 1440 | 1 day | 1,2,3,4,5,6,7
7 days
2 | 10080 | 7 days | 1,2,3,4,5,6,7
5 days
3 | 7200 | Weekdays | 2,3,4,5,6
etc.
Is this a way to go for, or should I store the rental time just in days?
Any help, advice, critics or cheers are helpful!
Thanks.
Depending on how you use this, storing rental time in minutes could cause issues around DST where you have 23 or 25 hours in a day.
Also storing the indices as comma-separated lists will cause you problems. I would make a mapping table. That column is not in normal form and will be tough to query.
I would honestly just make different tables for the different durations.
I would store the durations in seconds. Because it makes the whole thing easier to query and more felxible. Lets say you have those rental durations. Table durations:
d_id type duration
1 1 day 01
2 3 days 03
3 7 days 07
I would suggest that you use normal timestamps for the rentals. I would store the start and end timestamp. Lets say you have the following table.
In this example I'm using days instead of a timestamp just to make it easier to show. Let's say today is day 3. Table rentals:
customer start end
Bob 02 05
Joe 10 11
Ian 03 04
Let's say you want to want to get all the currently active rentals (Bob & Ian). You can fetch it like this:
SELECT * FROM `rentals` WHERE `start`<3 AND 3<`end`
You can find all which of rental type "1 day" (Ian) by using this query:
SELECT * FROM `rentals`,`durations` WHERE `end`-`start`=`duration` and `d_id`=1
The advantage of using timestamps is that you can very precisely set the rental start and end time. You can check how many hours and minutes the customer is too late with giving the object back. Then you can easily calculate the exact additional fees.

Best way to store weekly event in MySQL?

I have a table of weekly events that run on certain days of the week (e.g. MTWTh, MWF, etc.) and run on a certain time (e.g. 8am-5pm). What's the best way to store day of week information in MySQL to make retrieving and working with the data easiest? My CakePHP app is going to need to retrieve all events happening NOW().
For time of day, I would just use TIME. For days of the week, I had considered a 7-bit bitfield, a varchar ("MTWThFr" type deal) for the days of the week, but both of those seem like clunky solutions (the varchar being clunkier).
Any suggestions?
Here's a straightforward way:
EventID Title Mon Tue Wed Thu Fri Sat Sun BeginningDate EndDate
1 MyEvent 0 0 0 1 0 0 0 14-01-2010 14-01-2033
How to use:
Simply set a 1 on the days you want to run it. Since the 7-days calendar is not likely to change any time soon, that structure should be immutable. You can choose any combination of days.
To recap:
Run every Thursdays:
EventID Title Mon Tue Wed Thu Fri Sat Sun BeginningDate EndDate
1 MyEvent 0 0 0 1 0 0 0 14-01-2010 14-01-2033
Run every Thursdays & Mondays:
EventID Title Mon Tue Wed Thu Fri Sat Sun BeginningDate EndDate
1 MyEvent 1 0 0 1 0 0 0 14-01-2010 14-01-2033
Further more, you get only one row per event schedule, which is easier and cleaner to handle programmatically.
For example, to find all events to be executed on monday, do:
select * from Events where Mon = 1
Can you add an DayOfWeek column in your table and make it an int? Valid values for that would be 1 thru 7. You could add a constraint on that to enforce that rule. For time, how about a BeginTime columns and an EndTime column? They would be int's as well 0-24
For an event at 5:00 pm on Monday would look like this in your table
Event_ID DayOfWeek BeginTime EndTime
1 2 1700 1800
Why not have several lines, each line having only one column containing the day of week. This column would be just a simple :
ENUM("Monday", "Tuesday", ...)
Then, in PHP you could use date and strtotime functions to get the name of the day :
echo date('l');
echo date('l', strtotime('mon'));
// Outputs "Monday"
It is way more readable to store the name of the day.
In case anyone coming this way again I am using SMTWHFA quite efectively with a simple string search.
So Monday Wednesday Friday would be MWF and Sunday Monday Thursday would be SMH. Takes a while to get used to H=Thursday (second letter) and Saturday=A but it works!
Since there won't be any new days of the week invented (I hope!) you could just create a bool column for each day. Then, if you are running a query to find events on a Friday, it would simply be (with a bit of pseudocode):
SELECT eventName
FROM events
WHERE fridayBool = true
AND eventStartTime < NOW()
AND eventEndTime > NOW();
In that example the name of the column you would store in an array in your code, and check today's date to see what day of the week it is, which then selects the proper name out of the array before creating the query.
Not the most elegant, but it should work.
Edit...
Example table columns:
eventID
eventName
eventStartTime
eventEndTime
sundayBool
mondayBool
...
saturdayBool
Break the weekly information into a separate table entirely:
events: id, beginTime, endTime, name, description
eventsbyday: id, dayofweek, event_id
This will allow you to query eventsbyday according to the current day of the week:
SELECT events.name, events.beginTime, events.endTime FROM eventsbyday JOIN events ON eventsbyday.event_id=events.id WHERE dayofweek=0
This is very rough code, but the idea is to break out the weekly information, allowing you to have the same event associated with multiple days of the week.