October 17, 2005 at 10:08 am
Hi all.
I'm trying to develop a query for grouping help desk calls based on time of day received with the following groupings: 5:00 PM to 2:00 AM, 9:00 PM to 6:00 AM, 1:00 AM to 10:00 AM, and 9:00 AM to 6:00 PM. The date and time data is stored in the DB in a decimal format, so I'm having to convert these values to datetime, which was very challenging to begin with. Problem is when the time periods span 2 days I get no data back. I've tried including the date with the time and still no results. Any ideas on how I can resolve this?
Thanks!
TC
October 17, 2005 at 11:33 am
1. Please, Can you post some sample Data and DDL
2. If you include the date(with no time) in the grouping you should be fine
something like:
select date, timeSpan
from SourceOfData
group by date, Timespan
should return what you need. Without sample data I can't go further
* Noel
October 17, 2005 at 12:23 pm
Note that with a 24 hour clock, to determine if a specific time is with a range that spans midnight, such as 9:00 PM to 6:00 AM, two checks are needed: one for 9PM to Midnight (24) and the other for Midnight (00) to 6AM.
Try something along the lines of this:
Create table HelpDeskCalls
(CallIdinteger not null primary key
, CallTsdatetime not null
)
select count(*) as TotalCalls
,sum(CASE when DATEPART(hh,CallTs) between 17 and 24 OR DATEPART(hh,CallTs) between 00 and 02
then 1 else null end ) as [5:00 PM to 2:00 AM]
,sum(CASE when DATEPART(hh,CallTs) between 21 and 24 OR DATEPART(hh,CallTs) between 00 and 06
then 1 else null end ) as [9:00 PM to 6:00 AM]
,sum(CASE when DATEPART(hh,CallTs) between 01 and 10
then 1 else null end ) as [1:00 AM to 10:00 AM]
,sum(CASE when DATEPART(hh,CallTs) between 09 and 18
then 1 else null end ) as [9:00 AM to 6:00 PM]
From HelpDeskCalls
go
SQL = Scarcely Qualifies as a Language
October 17, 2005 at 1:48 pm
Actually I already determined that. My only concern is when grouping by day of week, as I think the data returned would actually only be for that specific date as opposed to spanning say 9:00 PM to Midnight Thursday and Midnight to 6:00 AM Friday, but since I'm reporting on a weekly basis I guess this isn't an issue. Here's a sample of the code I wrote:
SET ARITHABORT OFF
SET ARITHIGNORE ON
SET ANSI_WARNINGS OFF
SELECT DISTINCT CALL_HDW.CALLID_HDW AS CALLS_RCVD,
CALL_HDW.CALLGRP_HDW AS GRPID_HDW,
CALL_HDW.CALLOPR_HDW AS OPERID_HDW,
LEFT(CONVERT(DATETIME,CAST(((CONVERT(NCHAR,CALL_HDW.CALLDAT_HDW) -
((CONVERT(NCHAR,CALL_HDW.CALLDAT_HDW)/65536) * 65536))/256)
AS NCHAR(2))+'/'+
CAST(CONVERT(NCHAR,CALL_HDW.CALLDAT_HDW)-
((CONVERT(NCHAR,CALL_HDW.CALLDAT_HDW)/65536)*65536)-
((((CONVERT(NCHAR,CALL_HDW.CALLDAT_HDW) -
((CONVERT(NCHAR,CALL_HDW.CALLDAT_HDW)/65536) * 65536))/256))*256)
AS NCHAR(2))+'/'+
CAST(CONVERT(NCHAR,CALL_HDW.CALLDAT_HDW)/65536 AS NCHAR(4))),12)+
RIGHT(CONVERT(DATETIME,CAST(CAST(CONVERT(DATETIME,(CALL_HDW.CALLTME_HDW/16777216))
AS NUMERIC(2)) AS NCHAR(2)) +':'+
CAST(CAST(((CALL_HDW.CALLTME_HDW-
(CAST((CALL_HDW.CALLTME_HDW/16777216) AS NUMERIC(2))
*16777216))/65536) AS NUMERIC(2))AS NCHAR(2))),8) AS CALLTME_HDW
INTO #TIME
FROM CALL_HDW
SELECT GRPID_HDW,
OPERID_HDW,
CALLTME_HDW,
CASE WHEN DATEPART(HH,CALLTME_HDW)
BETWEEN 17
AND 24
OR DATEPART(HH,CALLTME_HDW) BETWEEN 00 AND 02
THEN CAST('5PM_to_2AM' AS VARCHAR(21))
WHEN DATEPART(HH,CALLTME_HDW)
BETWEEN 21
AND 24
OR DATEPART(HH,CALLTME_HDW) BETWEEN 00 AND 06
THEN CAST('9PM_to_6AM' AS VARCHAR(21))
WHEN DATEPART(HH,CALLTME_HDW)
BETWEEN 01
AND 10
THEN CAST('1AM_to_10AM' AS VARCHAR(21))
WHEN DATEPART(HH,CALLTME_HDW)
BETWEEN 09
AND 18
THEN CAST('9AM_to_6PM'AS VARCHAR(21))
ELSE CAST('WHATEVER' AS VARCHAR(21)) END AS CALLTME_HDW
FROM #TIME
DROP TABLE #TIME
The date and time data in this DB is in a decimal format, hence the protracted statements to convert to datetime.
Thanks,
Tim C.
October 17, 2005 at 3:06 pm
All your problems stem from using the wrong unit of measure (day). Radically simplify the solution by defining a "relative" work week for each shift. Create a table with the following four columns:
1. ShiftCode
2. SpanNbr
3. SpanStartMinsOffset
4. SpanStopMinsOffset
All offsets are from say Sunday 12am. You can quickly calculate all time spans for the week for each shift no matter which day boundaries are crossed.
Convert to "absolute" work week with something like this:
Select DateAdd(minute,@Sun, SpanStartMinsOffset) as AbsShiftStart
October 17, 2005 at 3:10 pm
What do you mean "decimal format"?
Is it number of days from any "zero day"?
If yes, there is no any problem.
1. Don't convert data in column you are filtering. SQL Server cannot predict result of the function, it must read whole table, convert every value, store it in tempdb, than scan this temporary table for requested values, join selected rows to original table, and than select requested rows.
No surprise it's gonna take 2 days for big enough table.
2. Set up index on the date-time column (I mean not datatype, but meaning of data). Because you select periods of data this index must be clustered.
3. Convert requested periods in your query to the same type as you have time periods stored in your table.
For example, for weekly periods:
WHERE CallTime%7 between convert(float, @TimeStart) and convert(float, @TimeEnd)
@TimeStart = convert(datetime, '1900-01-03 09:00)
@TimeEnd = convert(datetime, '1900-01-03 17:00)
This will return all calls on 3rd day of the week started from your "zero date" between 9am and 5pm.
P.S. Don't convert datetime to char type. Never. Except it's your main enemy's database.
_____________
Code for TallyGenerator
October 17, 2005 at 3:15 pm
I hope that post on relative work span offsets made sense. Create a view on your original table to handle the decimal to datetime conversions and hide that complexity forever. Hope this helps.
October 18, 2005 at 8:11 pm
And even better create computed columns
CALLTME_HDW%7 (for weekly periods) and
CALLTME_HDW%1(for dayly periods)
and set up indexes on it.
_____________
Code for TallyGenerator
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply