Solved

SQL Query to Convert Duration into rows per time period

Posted on 2004-04-19
5
694 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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction SQL Server Integration Services can read XML files, that’s known by every BI developer.  (If you didn’t, don’t worry, I’m aiming this article at newcomers as well.) But how far can you go?  When does the XML Source component become …
Introduction In my previous article (http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/SSIS/A_9150-Loading-XML-Using-SSIS.html) I showed you how the XML Source component can be used to load XML files into a SQL Server database, us…
Via a live example combined with referencing Books Online, show some of the information that can be extracted from the Catalog Views in SQL Server.
Via a live example, show how to backup a database, simulate a failure backup the tail of the database transaction log and perform the restore.

856 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