Solved

SQL Query to Convert Duration into rows per time period

Posted on 2004-04-19
5
690 Views
Last Modified: 2006-11-17
My first question, hope the points aren't stingy.
Using SQL 2000
I'm trying to come up with an "elegant" way to convert appointment rows into a visible schedule.  By elegant I mean I would prefer this to work in a view (i.e. no TSQL), but if it must be a query or even TSQL, so be it.  More specifically, I want to go from start and finish times to individual slots based on a predefined duration (for example, 30 minutes).  I already have a SQL view so that the data can be queried via Excel, but would like to show it in a similar fashion to a "schedule for the day".  I'm pretty sure I could create a TSQL query that does this but I was hoping for something a little more elegant.  

Here's an example:  Given an appointment at 8:30am with duration of 1.5 hours, create a row for every 15 minute slot so it can show up in Excel like a calendar.  Currently, Excel only sees this at 8:30am and 1.5 hours...I want it to see this as:
  8:30am, true
  9:00am, true
  9:30am, true
10:00am, false

Appointments will never carry past a given day.

Here is a portion of the existing query's SELECT

      Duration=CAST((DATEDIFF(minute, ap.ApptStart, ap.ApptStop)) AS int),

Thanks,
David
0
Comment
Question by:djharris
  • 3
  • 2
5 Comments
 
LVL 5

Expert Comment

by:chaniewskim
ID: 10864683
I think that simplest solution will be to create additional table with time slots (for ex. every 30 minutes) and then join this table with your schedule.

Then you could return an additional (computed) column indicating true where there is join and false where isn't
0
 

Author Comment

by:djharris
ID: 10866286
I've just created a table with timeslot AS datetime and duration as int.  

INNER JOIN TimeSlots ts ON
(ap.ApptStart - CAST(FLOOR(CAST(ap.ApptStart AS float)) AS datetime)) <= (ts.timeslot - CAST(FLOOR(CAST(ts.timeslot AS float)) AS datetime)) AND
(ap.ApptStop - CAST(FLOOR(CAST(ap.ApptStop AS float)) AS datetime)) > (ts.timeslot - CAST(FLOOR(CAST(ts.timeslot AS float)) AS datetime))

Any ideas on how to clean up the repetitive casting to get at just the time?
0
 

Author Comment

by:djharris
ID: 10866293
Oh, I meant to ask...you suggested this a slightly different way with a computed column.  What exactly did you have in mind?
0
 
LVL 5

Accepted Solution

by:
chaniewskim earned 125 total points
ID: 10866514
I'd go the other way: select timeslots and left-join appointments to then
This way you'll get a results of all timeslots in a day, paired with an information if there is an appointment in this time, which is exactly what you need if I understand right. I see that you have ApptStart and ApptStop (both datetime) in your appointments table, so if you had Timeslots table with Timeslot char(5) field (08:00, 08:30, 09:00, 09:30 - it compares well), then your query could look like (assumption: you have ApptID in Appointments):

SELECT DISTINCT timeslot, CASE WHEN ApptID IS NULL THEN 0 ELSE 1 END AS IsAppointment
FROM timeslots LEFT JOIN Appointments ON
      timeslot >=
            RIGHT('00' + CAST(DATEPART(hh,ApptStart) AS varchar), 2) + ':' + RIGHT('00' + CAST(DATEPART(mi,ApptStart) AS varchar), 2)
      AND timeslot <
            RIGHT('00' + CAST(DATEPART(hh,ApptEnd) AS varchar), 2) + ':' + RIGHT('00' + CAST(DATEPART(mi,ApptEnd) AS varchar), 2)
ORDER BY timeslot

To clean it you could store AppStart and AppEnd as char(5) (ex. '09:00') or move creation of that string to function.
To detect overlapping appointments you could also change it to:

SELECT timeslot, COUNT(ApptId) AS AppointmentsCount
FROM timeslots LEFT JOIN Appointments ON
      timeslot >=
            RIGHT('00' + CAST(DATEPART(hh,ApptStart) AS varchar), 2) + ':' + RIGHT('00' + CAST(DATEPART(mi,ApptStart) AS varchar), 2)
      AND timeslot <
            RIGHT('00' + CAST(DATEPART(hh,ApptEnd) AS varchar), 2) + ':' + RIGHT('00' + CAST(DATEPART(mi,ApptEnd) AS varchar), 2)
GROUP BY timeslot
ORDER BY timeslot

Does it help you?
0
 

Author Comment

by:djharris
ID: 10869516
Yes thank you...I started realizing that this morning when working with the data in Excel.  I was missing not only time slots, but also days (like when the person who's schedule I'm showing has no appointments for a given day).  I realize now that I need to extend this same idea to a full calendar of valid work days, with yet another LEFT JOIN on those.  A slower query to be sure, but a better end result.

I will award you the points.  Thank you for your detailed follou-up.
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Nowadays, some of developer are too much worried about data. Who is using data, who is updating it etc. etc. Because, data is more costlier in term of money and information. So security of data is focusing concern in days. Lets' understand the Au…
JSON is being used more and more, besides XML, and you surely wanted to parse the data out into SQL instead of doing it in some Javascript. The below function in SQL Server can do the job for you, returning a quick table with the parsed data.
Via a live example, show how to shrink a transaction log file down to a reasonable size.
Viewers will learn how to use the UPDATE and DELETE statements to change or remove existing data from their tables. Make a table: Update a specific column given a specific row using the UPDATE statement: Remove a set of values using the DELETE s…

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

24 Experts available now in Live!

Get 1:1 Help Now