Solved

SQL Query to Convert Duration into rows per time period

Posted on 2004-04-19
5
696 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Simplifying Server Workload Migrations

This use case outlines the migration challenges that organizations face and how the Acronis AnyData Engine supports physical-to-physical (P2P), physical-to-virtual (P2V), virtual to physical (V2P), and cross-virtual (V2V) migration scenarios to address these challenges.

Question has a verified solution.

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

Let's review the features of new SQL Server 2012 (Denali CTP3). It listed as below: PERCENT_RANK(): PERCENT_RANK() function will returns the percentage value of rank of the values among its group. PERCENT_RANK() function value always in be…
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…
This videos aims to give the viewer a basic demonstration of how a user can query current session information by using the SYS_CONTEXT function
Viewers will learn how to use the SELECT statement in SQL to return specific rows and columns, with various degrees of sorting and limits in place.

730 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