How do I add new rows to SQL automatically by time? - sql

I'm a pretty new programmer and I'm working on a project that I'm not sure how to make work. I'm hoping for some advice please.
Part of the project I'm working on will be used by a company to allow employees to sign up for lunch from their computers. I'm doing the project in MVC ASP.NET
The interface will look something like this:
----------------------
|1200 | Employee Dropdown Name 1
| Employee Dropdown Name 2
|---------------------
|1230 | Employee Dropdown Name 1
| Employee Dropdown Name 2
|---------------------
and on and on and on.
With this company, everything has to be recorded and stored. So, I already have a table with employee information. That will populate the drop down areas. Lunch times need to be stored in the database so it can be searched years down the line. So it has to be in a table.
The table get more tricky because not every time of the day is available for lunch (i.e. - no lunches after 0430 and before 0800).
My question is about how to create the future time slots in the database.
I could obviously make the table with all of these rows already in places for several years down the line. That's time-consuming, though, and I'll have to go back in in several years and fix it. Horrible idea.
What I'd LOVE to do is make it so every 24 hours, the database just automatically adds new rows with the next days times available - so just increment (at midnight, the program will just add the next day's times associated with that date (so at midnight on February 6, 2020, it will create February 7, 2020 0000, February 7, 2020 0030, etc. I've studied a lot but I'm still beside myself on how to make this work.
Thanks in advance everyone!!!

As I understand, you want to drive your interface from the database table so that the user can select Name 1 and Name 2 and a time slot and submit.
It sounds like you also want the available timeslots to be driven by the database also (ie, timeslot in table without names with it is availlable). This is not a good idea. As you mentioned, you would be inserting data that is not actually a record but a placeholder. That will be very confusing down the track when you come to query the data.
My approach would be to do the following:
* add NOT NULL constraints to all columns in your database (if your database supports this feature) or have your app complain very much about NULLS in any of the columns. There is no need for NULLS in your use case by the look of it.
the database should have a CHECK constraint that the time is within the allowable time range, and (assuming employees can not double book time slots) a CHECK constraint that there is no overlapping time slots, and also a UNIQUE constraint that ensures no duplicate times.... adjust to suit your needs.
your app populates times between 0800 and 1630 (8AM and 4:30PM) and also query the database for all records matching the current day so those booked slots can be removed from the list of available time slots... adjust to suit.
your app sends the user request of name and time slot to the DB. All the critical requirements are accepted or rejected by the DB schema and if there is something wrong, display an appropriate error in the app.
This way, your database is literally storing records of booked lunches.
I would NOT go down the path of pre inserting as then it becomes more complex as some records are "real" and some are artificially generated records to drive a GUI...
If you can't do the time slot calculations in your app rather than in the DB, then at least use a separate table that is maintained by a worker thread in your app OR if your DB supports it, a Stored Procedure which returns a table of available time slots.
I would use the stored procedure if I was avoiding doing complex time calculations in my app (also avoids need to worry about time zones - if you make sure to only store and display UTC times in your DB).

Having in mind structure like this:
LunchTimeSlots (id, time_slot)
Employee (id, name, preferred_time_slot_id, etc)
Lunches(employee_id, time_slot_id, date)
You need a scheduled job to add records to the "Lunches" table every midnight. How to define the job depends on your database vendor. But most of the popular rdbms have this feature. (f.e. mssql)
Despite it's possible to do what you want with db schedulers or any other scheduler, i would recommend to avoid such db design. It's always better to write real facts to the database like a list of employees or fact that lunch was served
to employee at 1pm today.
Unlike real facts, virtual data can be always generated "on-the-fly" by sql queries. F.e. by joining employees to list of dates from today till year 2100, we can get planned lunches for all employees for next 80 years.

Related

vb.net calculating booked appointment times from a list of available times?

I'm trying to find an efficient way to calculate the booked times for a user(object), given a list of free/available times for the same user\object.
I have an object that will return the "available" times for a given specific day. The duration/end time is fixed to 10 minutes.
Example Starting data:
12/23/2020 8:00 AM
12/23/2020 9:00 AM
12/23/2020 1:00 PM
In this case I need to generate the "unavailable" times and insert them into a database with a fairly simple schema:
start_date | end_date | start_time | end_time
The inserting is fairly trivial, i'm having a hard time determining the best way to calculate the unavailable timespans.
Using the example above i would need to generate the following timespans:
12/23/2020 12:00 AM - 7:59 AM
12/23/2020 08:11 AM - 8:59 AM
12/23/2020 09:11 AM - 12:59 PM
12/23/2020 1:11 PM - 11:59 PM
Any frameworks or libraries that can do the heavy lifting on this for me? Is it possible to solve this problem without looping through the results and calculating all of the offsets?
To anyone asking "why" - hooking together two legacy systems, one system returns the available appointments for a given date this needs to be plumbed into a system that needs the un-available appointments for a given date.
Well, first I written more tour booking systems then I can shake a stick at.
The one Rosetta stone that holds true?
You don't want to generate or have booking slots that are NOT being used in the system PERIOD!!!
Thus you ONLY ever enter into the system a valid booking (starttime, and end time). And that startTime should be a datetime column - this will VAST reduce the complexity of your queries. Given you have date and separate time? Well, then your queries will be more complex - I'll leave that to you.
Given the above? The simple logic to find a booking collision in ALL cases is this:
A collision occurs when:
RequestStartDate <= EndDate
and
RequestEndDate >= StartDate
Now in above, I assume date values, or datetime values.
So if I want a list of any booking for today?
RequestDDTStart = 2020-12-23 9 AM
RequestDTEnd = 2020-12-23 5 PM
And thus any collision can be found with this:
strWhere= dtRequestStartDate <= BookingEndDate" & _
" and dtRequestEndDate >= BookingStartDate"
Now, assumging .net, then above would be something like this as parameters
strWhere= #dtRequestStart <= BookingEndDate" & _
" and #dtRequestEnd >= BookingStartDate"
So, above would return all bookings for today 9 am to 5 pm
A REMARKABLE simple query! Now of course the above query could/would include the exam room, or hotel room or whatever as an additional criteria. But in ALL cases the above simple query returns ANY collision for that 9 am to 5 pm.
And the beauty of this system? As long as you never allow a over-lap into the booking system, then you can book a 10 minute or a 20 minute or a 30 minute session as ONE entry into the database. I would thus not need to create 3x 10 minute slots.
So, this means you NEVER have to create booking slots. The whole system will and can be driver with a simple start + end booking record. And as noted, then you can book 1 hour, or 40 minutes. Your input (UI) can simple limit the time span to increments of 10 minutes - but that's the UI part.
Now I suppose to display things in 10 minute increments on a screen? Well, then you would have to submit 6 requests per hour to "display" the time slots. For a whole day, that suggest for 9 am to 5 pm, you would have to run 8 x 6 = 48 requests to get a list of 10 minute increments. But then again, you COULD just show the existing bookings for a day, and allow new bookings to be added - but don't allow if there is a over lap.
So, as noted, the concept here is you don't really need "slots" in the database. I suppose you could try slots, but it makes the code a HUGE mess to deal with. if you ONLY ever store the start + end? Then I can say move the booking to another day by JUST changing the date. Or I can extend a booking from 10 minutes to say 20 or 40 minutes - and ONLY have to change the end time. As long as no overlap occurs with the above simple "test", then I can simple change the booking to be 40 minutes in length - and ZERO code to update multiple slots is required. And same goes for reducing a booking from 40 minutes to 10 minutes. Again ONLY the end time need be reduced - a ONE row update into the database.
So if at all possible, I would dump the concept of having "slots" in the database. I might consider such a design if a booking was only ever 10 minutes. But if 10 or 20 or 30 is allowed, then you don't need to store ANY un-used slots in the database, but ONLY ever store a valid booked slot. Empty un-used time can thus ALSO be found with the above query. (if the query returns records - then you can't book).
So display of free time in some UI becomes more of a challenge, but showing bookings that span 10 or 20 or whatever minutes is far more easy, and as noted, you can even change a whole booking to a different room by a ONE row update of the room ID. If no collision occurs, then you allow this booking - and you achieve this result by ONLY updating one simple booking record that represents that start + end time.
and this means you also NEVER store the booking totals in the database - you query them!
I also found that if I say store any booking totals in the database? Well, with complex code, we always found that the totals often don't match perfect. So then we wind up writing a routine to go though the data, sum up the totals and write those out.
But, if you never store any booked totals (say people on a bus, or people in a given hotel), then while the query for such display is somewhat more difficult, it becomes dead simple to remove a person from say a tour by simple null out of the tourID.
So, this display shows the above concepts in Action. And the available rooms in the hotel, people booked on bus, and even totals for "group tours" are ALL values NOT stored in the database:
So in above, people booked on bus, booked in rooms, and rooms used? All those values are NOT stored in the database. And no slots exist either. So if we have a bus, then we set the capacity of 46, but we do NOT create 46 slots to book into. So be it a bus, a hotel, a medical exam room? You don't create booking slots ahead of time, but simply insert bookings with a start + end, and then query against that concept.
So, to find a total on a bus (or say in a exam room), I query to find the total for that day. And if I want to move a group booking of 4 people from one bus to another? Then one FK update to the given bus they are on allows the whole system to "cascade" the existing values in the system. And same goes for moving a person from exam room #1 to #5. You only have to update the FK value of the exam room. If no collisions occur, then this again is a one row update. If you have multiple exam rooms, and multiple slots, then what should be a simple one row update in the database becomes a whole hodge podge of now having to update multiple booking slots with whacks of code.
So you book "use" of resources "into" a "day" a "bus" a room, but it is the act of that booking that consumes the time slots - not that you pre-create records or timeslots for each "range". This thus allows you to leverage the relatonal database model, and reduce huge amounts of code - since you not coding against "slots", but only that a exam room is open from 10 am to 4 pm. That available room for that day is thus ONLY ONE record you create in the system, and then you are now free to book into that one day given room range. The bookings into that one room for the day can be 10 minutes, or 40 minutes - but it ONLY one record being added into the database to achieve this goal (booking).
Regardless of the above, that simple collision query works for any collision (including a whole overlap, inside a existing span, or even the end or start overlaps any booking. And that query is dead simple - and it works for all collisions. So I don't have a library to share, but that simple booking collision finder query can thus drive the whole system based on that kind of simple query.

How to store availability information in SQL, including recurring items

So I'm developing a database for an agency that manages many relief staff.
Relief workers set their availability for each day in one of three categories (day, evening, night).
We also need to be able to set some part-time relief workers as busy on weekly, biweekly, and in one instance, on a 9-week rotation. Since we're already developing recurring patterns of availability here, we might as well also give the relief workers the option of setting recurring availability days.
We also need to be able to query the database, and determine if an employee is available for a given day.
But here's the gotcha - we need to be able to use change data capture. So I'm not sure if calculating availability is the best option.
My SQL prototype table looks like this:
TABLE Availability Day
employee_id_fk | workday (DATETIME) | day | eve | night (all booleans)| worksite_code_fk (can be null)
I'm really struggling how to wrap my head around recurring events. I could create say, a years worth, of availability days following a pattern in 'x' day cycle. But how far ahead of time do we store information? I can see running into problems when we reach the end of the data set.
I was thinking of storing say, 6 months of information, then adding a server side task that runs monthly to keep the tables updated with 6 months of data, but my intuition is telling me this is a bad fix.
For absolutely flexibility in the future and keeping data from bloating my first thought would be something like
Calendar Dimension Table - Make it for like 100 years or Whatever you Want make it include day of week information etc.
Time Dimension Table - Hour, Minutes, every 15 what ever but only for 24 hour period
Shifts Table - 1 record per shift e.g. Day, Evening, and Night
Specific Availability Table - Relationship to Calendar & Time with Start & Stops recommend 1 record per day so even if they choose a range of 7 days split that to 1 record perday and 1 record per shift.
Recurring Availability Table - for day of week (1-7),Month,WeekOfYear, whatever you can think of. But again I am thinking 1 record per value so if they are available Mondays and Tuesday's that would be 2 rows. and if multiple shifts then it would be multiple rows.
Now and here is the perhaps the weird part, I would put a Available Column on the Specific and Recurring Availability Tables, maybe make it a tiny int and store something like 0 not available, 1 available, 2 maybe available, 3 available with notice.
If you want to take into account Availability with Notice you could add columns for that too such as x # of days. If you want full flexibility maybe that becomes a related table too.
The queries would be complex but you could use a stored procedure or a table valued function to handle it fairly routinely.

Use domain of one table for criteria in another in ms Access query?

I am trying to create a report that displays 3 different numbers for each of my projects.
Contract Hours - Stored in projects table, 1 to 1 relationship
Worked Hours - Stored in linked table that will be updated using an external website reporting feature that will contain only data for the dates that are to be displayed in the report, one to many relationship needs to be a sum
Allocated Hours - Stored in a table in my database called allocations and contains data for all dates, one to many relationship needs to be summed.
Right now i have it set up in a way that the user has to type the data range for the report every time it is run, however the date range only actually applies to the Allocation data because the worked hours data comes filtered and the contract data is one to one.
What I would like to do is set up a query that can see the domain of the worked hours and apply it as a date criteria for the allocated hours.
I have attempted to use max and min values of the Worked hours and tried to get creative but I'm actually not even sure if this is possible because I cannot see any simple solution (although I know it should be possible and fairly simple)
Any help, suggestions, or recommendations are appreciated.

Monitoring Updates over Time Frames and/or SQL Query with Regex counting dates within string

This is probably a fork in the road question. I have a journal blog that date stamps a continuation of a single field within a record.
Example:
Proj #1 (ID): Notes (memo field:) 10/12/2012 - visited site. 10/11/2012 - updated information. 10/11/2012 - call client. 10/10/2012 - Input information.
Proj #2 (ID): Notes (memo field:) 10/10/12 - visited site. 10/10/2012 - call client. 10/9/2012 - Input information. 10/1/2012 - Started project. etc etc...
I need to count how many updates where made over a specific time frame. I know I can create a hidden field and add + 1 everytime there is an update which is useful for an OVERALL update count... but how can i keep track of number of updates over the last 5 days. Like the example above you may update it twice in one day and I may not care about updates made 2 weeks ago.
I think I need to create an SQL that counts the number of "dates" since 10/10/12 or since 10/2/12 etc.
I have done the SQL: SELECT memo FROM Projects WHERE memo IN ('%10/10/12%', '%10/9/2012%' etc)
and then the Len(memoStringCombined) - Len(Replace(searchword""etc)/Len(searchword) and it works fine for countings a single date... but if I have count multiple dates over 30 days it gets to be quite cumbersome to keep rewriting each search word. Is there a regex or obj that can loop through this for me?
Otherwise any other suggestions for counting updates between time frames would be greatly appreciated.
BTW - I can't really justify creating a new table dedicated to tracking updates because there will be 100's of updates for close to 10,000 records which means the update tracking table will be more monstrous than the data... or am I wrong with that idea too?

Recurring Orders

Hi everyone I'm working on a school project, and for my project I chose to create an ecommerce system that can process recurring orders. This is for my final project, I'll be graduating in May with an associates in computer science.
Keep in mind this is no where a final solution and it's basically a jumping off point for this database design.
A little background on the business processes.
- Customer will order a product, and will specify during checkout whether it is a one time order or a weekly/monthly order.
- Customer will specify a location in which to pick up their order (this location is specific only to the order)
- If the value of the order > 25.00 then it is accepted otherwise it is rejected.
- This will populate the orders_test and order_products_test tables respectively
Person on the back end will have a report generated for deliveries for the day based on these two tables.
They will be able to print it off and it will generate a list of what items go to what location.
Based on the following criteria.
date_of_next_scheduled_delivery = current date
remaining_deliveries > 0
Once they are satisfied with the delivery list they will press "Process Deliveries" button.
This will adjust the order_products_test table as follows
Subtract 1 from remaining_deliveries
Insert current date into date_of_last_delivery_processed
Based on delivery_frequency (i.e. once, weekly, monthly) it will change the date_of_next_scheduled_delivery
status values in the order_products_test table can either be active, hold, or canceled, expired
I just would like some opinions if I am approaching this correctly or if I should scratch this approach and start over again.
A few thoughts, though not necessarily complete (there's a lot to your question, but hopefully these points help):
I don't think you need to keep track of remaining deliveries. You only have 2 options - a one time order, or a recurring order. In both cases, there's no sense in calculating remaining deliveries. It's never leveraged.
In terms of tracking the next delivery date, you can just keep track of the day of the order. If it's recurring -- monthly or weekly, regardless -- everything is calculable from that first date. Most DB systems (MySQL, SQL Server, Oracle, etc) support more than enough date computation flexibility so that you can calculate this on the fly, as opposed to maintaining such a known schedule.
If the delivery location is only specific to the order, I see no use in creating a separate table for it -- it's functionally dependent on the order, you should keep it in the same table as the order. For most e-commerce systems, this is not the case because they tend to associate a list of delivery locations with accounts, which they prompt you about when you order more than once (e.g., Amazon).
Given the above, I bet you can just get away with 2 of your 4 tables above -- Account and Order. But again, if delivery locations are associated with Accounts, I would indeed break that out. (but your question above doesn't suggest that)
Do not name your tables with a "_test" suffix -- it's confusing.